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。