petite-vue源码剖析-ref的工作原理

vue

ref内部的工作原理十分简单,其实就是将指令ref:refv-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/fsjohnhuang/p/16006899.html 肥仔John

以上是 petite-vue源码剖析-ref的工作原理 的全部内容, 来源链接: utcz.com/z/380960.html

回到顶部