一直以来,我对于 VueJS 中对于使用 ref 注册的组件,在使用 $refs 调用时,为什么有时候是一个 DOM元素/组件实例,是时候会是一个实例数组。
所以在很长一段时间内我觉得 ref 注册的的组件在使用 $refs 调用时有很大的不确定性,虽然我的弹窗组件一直都是用的 $refs.modal.open() 来打开的。
直到前一段时间,我在一个场景下想在 v-for 循环渲染的组件下 slot 模板中想使用 ref 注册成一个实例集合来调用时,发现怎么样重写返回的都只是一个组件实例,而不是一个组件实例集合。
所以有了这样一篇笔记。
注册 | ref
用来给元素或子组件注册引用信息。引用信息将会注册在父组件的 $refs 对象上。
- 如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;
- 如果用在子组件上,引用就指向组件实例:
关于 ref 注册时间的重要说明:因为 ref 本身是作为 渲染结果 被创建的,在初始渲染的时候你不能访问它们 - 它们还不存在!$refs 也 不是响应式 的,因此你不应该试图用它在模板中做数据绑定。
所以不要在 mounted() 之前的生命周期钩子里边直接使用 $refs 来获取元素,
或者在没有渲染组件的情况下调用元素内的属性或方法,如果一定要的话,记得放在 $nextTick() 里。
使用 | $refs
一个对象,持有注册过 ref attribute 的所有 DOM 元素和组件实例。
- 只读
- 允许父级组件通过
$refs来访问子组件实例内部元素的访问,比如来访问子组件实例内的data和methods- 当
ref和v-for一起使用的时候,将得到一个 DOM 节点数组 或 包含了对应数据源 的组件实例的。
1、什么时候只返回一个组件/DOM实例
一般来说,直接在一个没有使用 v-for 循环的元素上使用 ref 注册的元素,在使用 this.$refs.xxx 获取时,返回的只会是一个组件实例。
2、什么时候返回一个实例集合
按照文档上边来看,在使用 v-for 循环的元素上使用 ref 注册的元素,在使用 this.$refs.xxx 获取时,会返回一个实例集合。
有没有其他办法?比如我不是使用 v-for 循环出来的实例,但是我想注册在同一个 ref 下。
暂时没有办法。
附:
ref — Vue.js
vm.$refs — Vue.js
访问子组件实例或子元素 — Vue.js
Document.querySelectorAll - MDN
querySelectorAll 方法相比 getElementsBy 系列方法有什么区别?- 知乎