文本属于个人分析源码笔记,如果哪里不明白的话,请评论留言其实ref
的实现原理比较简单,如果是使用在普通上获取的是元素el,反之如果是组件上,就是组件实例
demo
实例demo地址
const { render, h, getCurrentInstance } = Vue
const MyComponent = {
setup() {
return () => h('p', {}, '123')
}
}
const VueComponent = {
setup(props, ctx) {
const internalInstance = getCurrentInstance()
const clickHandle = () => {
alert('111')
console.log(internalInstance.proxy.$refs)
}
return () => h(MyComponent, { ref: 'myRef', onClick: clickHandle })
}
}
render(h(VueComponent), document.getElementById('app'))
上述实例中,当打印internalInstance.proxy.$refs
的时候,对象中包含key为myRef
, value为子组件实例。那是如果形成的呢
源码分析
地址:
packages\runtime-core\src\renderer.ts
函数:patch
if (ref != null && parentComponent) {
setRef(ref, n1 && n1.ref, parentSuspense, n2 || n1, !n2)
}
上述实例是针对属性中存在ref
的,而且当前实例存在的时候,对ref
进行赋值
地址:
packages\runtime-core\src\rendererTemplateRef.ts
函数:setRef
// 如果是组件 就是组件实例 反之就是dom
const refValue =
vnode.shapeFlag & ShapeFlags.STATEFUL_COMPONENT
? getExposeProxy(vnode.component!) || vnode.component!.proxy
: vnode.el
const value = isUnmount ? null : refValue
} else if (_isString) {
// 直接赋值 最有价值的一句话
refs[ref] = value
整个方法太长了。很多代码对我们来说是无用的,上述的两段话才是关键点。如果想看整个方法的话,可以上文写的地址进行dubgger调试
结束
以上就是简单的组件中使用
ref
的分析。有什么问题欢迎留言
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)