Vue2 的 ref
主要通过以下机制实现:
编译阶段识别模板中的 ref
属性,将其绑定到虚拟节点(VNode)上。
data = { ref: "xxxRef", ... }
创建真实节点时区分组件和 DOM:
如果是组件,Vue 会通过 vnode.componentInstance
拿到组件实例;
如果是 DOM 元素,则通过 vnode.elm
获取真实 DOM。
注册 Ref
// src/core/vdom/modules/ref.js
export function registerRef(vnode: VNodeWithData, isRemoval: ?boolean) {
const key = vnode.data.ref
if (!key) return
const vm = vnode.context
const ref = vnode.componentInstance || vnode.elm // 关键判断点
const refs = vm.$refs
const dynamic = vnode.data.refInFor
// ...
if (typeof ref === 'object' && ref instanceof Vue) {
// 组件实例处理
setRef(refs, key, ref, vm, dynamic)
} else {
// DOM 元素处理
setRef(refs, key, ref, vm, dynamic)
}
}
注册时机:
ref
在 insert
钩子(组件挂载完成后)注册到父组件的 $refs
;ref
在元素插入页面后立即注册。动态管理:在组件销毁或 DOM 移除时,自动清理 $refs
中的引用。
v-for 场景下,$refs.xxx
会是一个数组,存储多个实例或 DOM。