共计 1194 个字符,预计需要花费 3 分钟才能阅读完成。
ref
外部的工作原理非常简略,其实就是将指令 ref
、:ref
或v-bind:ref
标识的元素实例存储到以后作用域的 $refs
对象中,那么咱们就能够通过 this.$refs
获取对应的元素实例。但因为作用域继承上有点小窍门,所以咱们能从 this.$refs
获取的元素实例还是须要留神一下。上面让我为你一一道来吧!
深刻 ref
工作原理
// 文件 ./src/directives/ref.ts | |
export const ref: Directive = ({ | |
el, | |
ctx: {scope: { $refs} | |
}, | |
get, | |
effect | |
}) => { | |
let prevRef: any | |
effect(() => { | |
// 获取指向元素的属性名称 | |
const ref = get() | |
$refs[ref] = el | |
// 因为属性名称是能够动静生成的(:ref="name"),若新旧对应的属性名称不同,则清理旧属性 | |
if (prevRef && ref != prevRef) {delete $refs[prevRef] | |
} | |
prevRef = ref | |
}) | |
return () => {prevRef && delete $refs[prevRef] | |
} | |
} |
这段实现是不是长篇累牍呢?当初让咱们把眼光转向上下文对象 (Context) 的构建吧
// 文件 ./src/context.ts | |
export const createScopedContext = (ctx: Context, data = {}) => { | |
onst parentScope = ctx.scope | |
const mergedScope = Object.create(parentScope) | |
Object.defineProperties(mergedScope, Object.getOwnPropertyDescriptors(data)) | |
// $refs 形成 $refs 对象的原型链 | |
mergedScope.$refs = Object.create(parentScope.$refs) | |
// ...... | |
} |
$refs 形成 $refs 对象的原型链,那么咱们就能够这样援用元素实例
createApp({ | |
App: { | |
$template: ` | |
<div ref="container"> | |
<div v-scope="Modal"></div> | |
</div> | |
`, | |
Modal: { | |
$template: ` | |
<button @click="handleHide">Hide</button> | |
`, | |
handleHide() {this.$refs.container.style.display = 'none'} | |
} | |
} | |
}).mount('[v-scope]') |
总结
下一篇《petite-vue 源码分析 - 优化伎俩 template 详解》咱们将着手解决 petite-vue 在线模板和在线渲染造成用户体验待优化的问题,敬请期待。
尊重原创,转载请注明来自:https://www.cnblogs.com/fsjoh… 肥仔 John
正文完
发表至: javascript
2022-03-15