本篇内容介绍了“Vue.slot原理及slot是如何实现的”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
成都创新互联长期为近千家客户提供的网站建设服务,团队从业经验10年,关注不同地域、不同群体,并针对不同对象提供差异化的产品和服务;打造开放共赢平台,与合作伙伴共同营造健康的互联网生态环境。为河津企业提供专业的做网站、成都做网站,河津网站改版等技术服务。拥有十余年丰富建站经验和众多成功案例,为您定制开发。
一、回顾 slot 用法
1. 默认插槽
默认插槽
页面展示效果如图:
2. 具名插槽
接着上述的案例,添加具名插槽
header,代码如下:header 具名插槽
默认插槽
如上代码块可以发现:
子组件中的
slot标签带上了一个名为name的属性,值为header父组件中的
template标签带上了v-slot的属性,值为header页面展示效果如图:
3. 作用域插槽(slot-scope)
再接着上述案例,添加作用域插槽
footer,代码如下header 具名插槽
默认插槽
footer 具名 + 作用域插槽
{{ slotProps.footerInfo.text }}
如上代码块可以发现:
子组件中的
slot标签除了有name=footer的属性,还有一个:footerInfo="footerInfo"的属性(作用就是传递子组件数据)父组件中的
template标签不仅有v-slot:footer,并且还有一个赋值操作="slotProps",在模版的双括号语法中,直接通过slotProps访问到 子组件的footerInfo页面展示效果如图:
好了,简单回顾完用法后,笔者在这里先提三个问题:
普通插槽、 作用域插槽 的 vNode 是在哪个环节生成的,render 父组件时还是子组件时?
作用域插槽 为什么能在父组件访问到子组件的数据?
普通插槽 跟 作用域插槽 在实现上有区别吗?
我们带着疑问接着往下看!
二、不同
slot的编译区别我们根据上述最终的案例代码,执行一下打包命令,看看 Vue 在编译模板的时候,是怎么处理我们的
slot的!事不宜迟,赶紧build一哈~(偷偷告诉大?,Vue处理 作用域插槽跟 普通插槽的差异就是从编译开始的,也就是 render函数 会有所不同)这里笔者顺便使用
v2.5的具名插槽写法给大?参照一下(对具名插槽header做改写,使用slot="header"的写法),大家可以看下v2.6、v2.5具名插槽的 写法、实现 上的区别~反正也不难,也就顺便带出来看看了
上图左边是
v2.6、右边是v2.5的,这里,我们集中关注:
scopedSlots属性。使用作用域插槽的footer的 render函数 是放在scopedSlots里的,并且 函数中 还有接收一个参数
my-slot的children。可以发现,默认插槽的render函数一直都是作为当前组件的childre节点,放在 当前 组件render函数 的第三个参数中关注
header两种具名插槽写法的区别。
v2.6中,我们使用了具名插槽,但是又未使用 作用域插槽的 header 也被放在了
scopedSlots,但是函数的参数为空,这点跟作用域插槽有区别。v2.5中, 具名插槽header 仅仅作为
my-slot组件的children节点,并且其render函数的第二个参数中有一个slot的属性。其实根据上述编译后的结果,我们不妨这样猜测:
默认插槽直接在父组件的
render阶段生成vNode。
子组件
render时,可能通过某种手段取得已经生成好的插槽vNode用作自己的slot节点。因为观察上述默认插槽的render函数:
e("h2", [t._v("默认插槽")]),直接就是my-slot组件的childre节点(位于my-slot组件的第三个参数)。作用域插槽是在子组件
render阶段生成vNode。
因为我们观察作用域插槽
footer的编译后结果,其不作为my-slot组件的 children,而是被放在了my-slot组件的 第二个参数data中的一个scopedSlots属性里。并且,作用域插槽的 render 函数 外层的 funciton 接收了一个参数。如果在执行子组件 render 的时候调用,那完全可以拿到子组件的数据。
这里放出具体的 作用域插槽打包后代码,大家一看就很清晰了:
{ scopedSlots: t._u([ { key: "footer", // 函数接收了一个参数n fn: function (n) { return [ // h2 标签的 render 函数 e("h2", [t._v("footer 具名 + 作用域插槽")]), // p 标签的 render 函数,这里可以看到编译后是:n.footerInfo.text e("p", [t._v(t._s(n.footerInfo.text))]) ] } } ]) }三、
slot实现原理1. 断点调试
为了方便大家看调试结果,当前项目的组件结构主要是这样,有三大层:
Vue->->这里笔者在运行时代码
initRender()、renderSlot()中,打上 debugger,直接带大火看看执行流程。这里简单介绍下两个方法:
initRender:获取
vm.$slot。组件初始化时执行(比如执行到my-slot组件时,可从vm.$slot 获取父组件中的slot vNode,也就是我们的 默认插槽)renderSlot:把组件的
slot替换成真正的插槽vNode接下来直接看实验截图:
1、先是进入
initRender()(这里跳过初始化大Vue、App的过程)。直接到初始化my-slot组件过程。【 简单解释:由于App组件执行render得到 App组件vNode,在patch过程中 遇到vue-component-my-slot的 vNode ,又执行my-slot组件的 初始化流程。】
我们不难发现,图中此时正值
my-slot组件的init阶段。
再往下执行,我们可以得到 App组件中的
的vNode,赋值给默认插槽
vm.$slot(这里我们记住,默认插槽的 vNode 已经得到)
2、再是进入
renderSlot()。接着上面继续单步执行,会走到renderSlot中。这时候,已经进入到my-slot组件的render阶段了。回顾第一步中,此时我们手握 默认插槽的vNode,并存在vm.$slot.default中header插槽
按顺序走,先是 render 排第一的 header 的 vNode。如图所示,会走到断点处,我们接着单步
直接进入执行我们 header插槽 的render函数执行处。根据调试步骤,我们可以肯定,放置在
scopedSlots属性中的 render函数,是在子组件 render 的时候执行
得到 header插槽 的 vNode
默认插槽
继续单步走,这次轮到 默认插槽 了!如图所示,这里的
key正是'default'。可以发现,这里并没有像上面 header插槽 一样,去执行 render,而是直接将我们之前得到的 插槽vNode返回了。
得到 default插槽 的 vNode
作用域插槽
前面都跟 header插槽 一致,都是会在 my-slot 组件中 执行插槽的 render。我们直接单步到 render 处看看有什么区别。这里可以得出,function处传入的参数正是我们子组件
my-slot的data数据,这就是为什么我们在App组件能通过作用域插槽访问到子组件数据的原因了
最后也是返回 footer插槽 的vNode。好了,验证过程结束~
2. 总结插槽实现原理
其实上面的流程只是论证过程,大家不可以不必深陷其中。笔者在这里直接根据实践过程,给大伙总结出结论!也就是要回到我们一开始的三个问题!
1、普通插槽、 作用域插槽 的 vNode 是在哪个环节生成的,render 父组件时还是子组件时?
默认插槽,不管
v2.5、v2.6的写法,都是在 父组件中生成vNode。vNode存在vm.$slot中。待子组件render到插槽时,会直接拿到 父组件的vNode具名插槽两个版本情况不一。根据编译结果可知:
v2.5的写法,跟默认插槽是一样的,在父组件生成vNode,子组件直接拿来用
v2.6中,直接时在 子组件 中才去执行插槽render,生成插槽vNode。作用域插槽。不管版本,都是在子组件中进行render的。
大家不妨这么理解,模版编译后,只要是被放在 scopeSlots属性中的插槽,都会在子组件执行 render 的时候才会去生成vNode。
2、作用域插槽 为什么能在父组件访问到子组件的数据?
作用域插槽只有子组件render的时候,才会执行render生成vNode。并且,作用域插槽的 render 函数能接参数,从而获得子组件的数据。就是这样形成了作用域插槽!所以我们能在父组件中,访问到子组件的data数据。
3、普通插槽 跟 作用域插槽 在实现上有区别吗?
有区别。
普通插槽。如果是
v2.5,具名插槽 和 默认插槽 都只在 父组件 render 的时候生成 vNode,子组件要 渲染slot 的时候,直接在父组件实例的 $slot 中获取已经是vNode的数据。普通插槽。如果是
v2.6,具名插槽 虽然是在子组件中执行的 render,但是其不接收参数。作用域插槽。不管
v2.5还是v2.6,都只在 子组件执行 render,并且能接收参数。“Vue.slot原理及slot是如何实现的”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注创新互联网站,小编将为大家输出更多高质量的实用文章!
网页标题:Vue.slot原理及slot是如何实现的
网页路径:http://www.jxjierui.cn/article/jcsocs.html


咨询
建站咨询












