”ref<HTMLElement>() ”写法问题,请教大佬?

作者站长头像
站长
· 阅读数 6
const nav = ref<HTMLElement>()
const nav = ref<HTMLElement|null>(null)
const nav = ref(null)
const nav = ref('')

在nav标签上加ref的话,这几种定义写法有啥区别?都可以吗?※现在用的是第二种写法

我在使用这个nav时候,ts提示我 navWidth = nav.value.clientWidth 这样的写法不对,应该是 navWidth = nav.value?.clientWidth但是在使用navWidth这个变量时候,navWidth可能为定义。这种情况该怎么写好点呢?必须这样加if判断条件吗 if(nav.value){}

问题2假如我想定义一个div的关联ref,那我用HTMLElementHTMLDivElement都可以是吧?有啥好的规约吗?像 nav这种标签是没有HTMLNavHTML这样的接口,这种时候怎么办嘞?既然都是HTMLElement的子类,为啥要HTMLDivElement呢,每次在定义时候都用HTMLElement

回复
1个回答
avatar
test
2024-07-05

既然你是用在 TS 里的,后两种写法等于直接丧失了类型信息,直接排除。

其次直接 ref<HTMLElement>() 就好,用不着声明成 ref<HTMLElement | null>

因为 ref() 这个方法的函数签名本身就已经是 function ref<T = any>(): Ref<T | undefined> 了,Vue 已经帮你做好了值可能是未定义的处理了,用不着你多此一举声明出来。

// 没有初始值,此时 a 的类型为 Ref<number | undefined>
let a = ref<number>(); 
// 有初始值,此时 b 的类型为 Ref<number>
let b = ref<number>(1);

我理解为你这个 ref 是要用在 template 里绑定到一个元素或组件的,那么它在 mount 之前确实会是 undefined 的。但如果你确认你的调用一定是在 mount 之后、并且这个元素本身也不存在 v-if 之类的会导致它有可能被销毁,那么直接用非空断言符 ! 即可:

nav.value!.balabala

只用你不能确定的情况下,才需要判断一下是否非空。


HTMLDivElementHTMLElement 多了一个 align 属性。如果你并非用到某个特定元素类型的特有成员(常见于 HTMLImageElementHTMLVideoElement 等),一律声明成 HTMLElement 即可,可以减轻心智负担。

回复
likes
适合作为回答的
  • 经过验证的有效解决办法
  • 自己的经验指引,对解决问题有帮助
  • 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
  • 询问内容细节或回复楼层
  • 与题目无关的内容
  • “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容