关于vue3如何写hooks的问题?
export function useChangeTableHeaderWidth(list) {
const time = Date.now()
const getWidthClass = `getWidth${time}`
const setWidthClass = `setWith${time}`
function resizeStep(setWidthElement: HTMLElement) {
const fontSize = window.getComputedStyle(setWidthElement).fontSize
let size = parseInt(fontSize)
const scrollwidth = setWidthElement.scrollWidth
const clientWidth = setWidthElement.clientWidth
if (scrollwidth > clientWidth && size > 0) {
size -= 1
setWidthElement.style.fontSize = size + 'px'
requestAnimationFrame(() => {
resizeStep(setWidthElement)
})
}
}
watch(
list,
() => {
const getWidth = document.getElementsByClassName(getWidthClass)
const setWidth = document.getElementsByClassName(setWidthClass)
for (const index in getWidth) {
if (Object.prototype.hasOwnProperty.call(setWidth, index)) {
/* 获取td的宽度,设置给th */
const getWidthElement = getWidth[index]
const width = getWidthElement.clientWidth
const setWidthElement = setWidth[index] as HTMLElement
// 这样写要去eslintrc文件里关闭对jsx的语法检查
// let setWidthElement = <HTMLElement>setWidth[index]
setWidthElement.style.width = width + 'px'
/* title字体大于宽度的时,让字体变小 */
const scrollwidth = setWidthElement.scrollWidth
const clientWidth = setWidthElement.clientWidth
if (scrollwidth > clientWidth) {
resizeStep(setWidthElement)
}
}
}
},
{
flush: 'post',
},
)
return [getWidthClass, setWidthClass]
}
如何限值list是ref值,亦或者即使传入的是普通值,也可以触发watch?还有就是这个hooks中的watch在使用了hooks之后一直存在吗,还是说组件销毁了watch就自动销毁,还是需要在这个hooks在写上组件卸载时手动销毁。
我记得antfu之前有个演讲提到过在hooks里用geter函数和tovalue、toref来提升兼容性,但是我记不清了,不知道能不能使用在这里,还有个effectScope我记得写hooks的时候好像也挺有用。
明显的,watch 需要监听一个响应式的值,所以你传入的 list 必须是响应式的。你如果想要限制传入的值,可以通过给 list 添加ts类型,或者通过RefSymbol来运行时判断是否是一个 ref 。
watch 不需要手动销毁,组件销毁时会自动销毁。
可以看看 vueuse 的仓库学习怎么写。