全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

Vue.js之slot深度复制详解

前言

在Vue中,slot是一个很有用的特性,可以用来向组件内部插入一些内容。slot就是“插槽”的意思,用大白话说就是:定义组件的时候留几个口子,由用户来决定插入的内容。

例如我们定义一个组件MyComponent,其包含一个slot:

Vue.component('MyComponent', {
 template: `
 <div>
  <slot></slot>
 </div>
 `
})

当调用<MyComponent>123</MyComponent>时,会渲染为如下DOM结构:

<div>
 123
</div>

现在又有新需求了,我们希望调用<MyComponent>123</MyComponent>时,渲染出这样的DOM结构:

<div>
 123
 123
</div>

看起来很容易实现,即再为MyComponent添加一个slot:

Vue.component('MyComponent', {
 template: `
 <div>
  <slot></slot>
  <slot></slot>
 </div>
 `
})

渲染出的结构也确实如你所愿,唯一美中不足的是控制台有一个小小的Warning:

Duplicate presence of slot "default" found in the same render tree

如果你不是强迫症患者,这时候你可以收工安心回家睡觉了。直到有一天你的同事向你抱怨,为什么向MyComponent插入一个自定义组件会渲染不出来?

例如有一自定义组件MyComponent2:

Vue.component('MyComponent2', {
 template: `
 <div>456</div>
 `
})

当调用<MyComponent><MyComponent2></MyComponent2></MyComponent>时,预期渲染为如下DOM结构:

<div>
 <div>456</div>
 <div>456</div>
</div>

为什么不能正常工作呢?估计是前面的那个Warning搞得鬼,通过查询发现在Vue 2.0中不允许有重名的slot:

重名的 Slots 移除

同一模板中的重名 已经弃用。当一个 slot 已经被渲染过了,那么就不能在同一模板其它地方被再次渲染了。如果要在不同位置渲染同一内容,可一用 prop 来传递。

文档中提示可以用props来实现,然而在我的用例中显然是不合适的。经过搜索后,最靠谱的方法是手写render函数,将slot中的内容复制到其他的位置。

将之前的MyComponent改为render函数的方式定义:

Vue.component('MyComponent', {
 render (createElement) {
 return createElement('div', [
  ...this.$slots.default,
  ...this.$slots.default
 ])
 }
})

在上面的定义中我们插入了两个this.$slots.default,测试下能不能正常工作。然而并没有什么卵用,Vue文档在render函数这一章有以下说明:

VNodes 必须唯一

所有组件树中的 VNodes 必须唯一

这意味着我们不能简单地在不同位置引用this.$slots.default,必须对slot进行深度复制。深度复制的函数如下:

function deepClone(vnodes, createElement) {
 function cloneVNode (vnode) {
 const clonedChildren = vnode.children && vnode.children.map(vnode => cloneVNode(vnode));
 const cloned = createElement(vnode.tag, vnode.data, clonedChildren);
 cloned.text = vnode.text;
 cloned.isComment = vnode.isComment;
 cloned.componentOptions = vnode.componentOptions;
 cloned.elm = vnode.elm;
 cloned.context = vnode.context;
 cloned.ns = vnode.ns;
 cloned.isStatic = vnode.isStatic;
 cloned.key = vnode.key;
 return cloned;
 }
 const clonedVNodes = vnodes.map(vnode => cloneVNode(vnode))
 return clonedVNodes;
}

上面的核心函数就是cloneVNode() ,它递归地创建VNode,实现深度复制。VNode的属性很多,我并不了解哪些是关键属性,只是参照着Vue的源码一并地复制过来。

基于以上函数,我们更改MyComponent的定义:

Vue.component('MyComponent', {
 render (createElement) {
 return createElement('div', [
  ...this.$slots.default,
  ...deepClone(this.$slots.default, createElement)
 ])
 }
})

经测试,一切正常。

总结

在Vue 1.0中重名的slots并不会出现什么问题,不知道为什么在2.0中取消了这个功能。我听说React提供了复制Element的标准函数,希望Vue也能提供这个函数,免得大家踩坑。以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。


# vue.js  # slot  # vuejs  # 怎么使用  # 深入理解vue中slot与slot-scope的具体使用  # Vuejs第十一篇组件之slot内容分发实例详解  # vue 组件中slot插口的具体用法  # 深入浅析Vue中的slots/scoped slots  # vue中slot(插槽)的介绍与使用  # 详解vue slot插槽的使用方法  # vue中父子组件注意事项  # 传值及slot应用技巧  # Vue 技巧之控制父类的 slot  # 可以用  # 自定义  # 递归  # 插槽  # 的是  # 是一个  # 有什么  # 几个  # 有一  # 文档  # 过了  # 你可以  # 也能  # 又有  # 其他的  # 要在  # 很容易  # 你不是  # 大白  # 美中不足 


相关文章: 北京制作网站的公司,北京铁路集团官方网站?  沈阳个人网站制作公司,哪个网站能考到沈阳事业编招聘的信息?  建站VPS推荐:2025年高性能服务器配置指南  C++ static_cast和dynamic_cast区别_C++静态转换与动态类型安全转换  如何使用Golang table-driven基准测试_多组数据测量函数效率  枣阳网站制作,阳新火车站打的到仙岛湖多少钱?  开源网站制作软件,开源网站什么意思?  如何解决ASP生成WAP建站中文乱码问题?  网站规划与制作是什么,电子商务网站系统规划的内容及步骤是什么?  如何通过免费商城建站系统源码自定义网站主题与功能?  网站制作话术技巧,网站推广做的好怎么话术?  建站之星如何快速生成多端适配网站?  如何通过网站建站时间优化SEO与用户体验?  网站制作公司广州有几家,广州尚艺美发学校网站是多少?  已有域名和空间,如何快速搭建网站?  如何选择适配移动端的WAP自助建站平台?  一键网站制作软件,义乌购一件代发流程?  高防服务器租用指南:配置选择与快速部署攻略  深圳企业网站制作设计,在深圳如何网上全流程注册公司?  广东企业建站网站优化与SEO营销核心策略指南  建站之星安装步骤有哪些常见问题?  中山网站制作网页,中山新生登记系统登记流程?  建站主机是否属于云主机类型?  如何通过云梦建站系统实现SEO快速优化?  网站制作模板下载什么软件,ppt模板免费下载网站?  建站之星IIS配置教程:代码生成技巧与站点搭建指南  香港服务器部署网站为何提示未备案?  建站之星ASP如何实现CMS高效搭建与安全管理?  山东云建站价格为何差异显著?  制作企业网站建设方案,怎样建设一个公司网站?  如何高效配置IIS服务器搭建网站?  洛阳网站制作公司有哪些,洛阳的招聘网站都有哪些?  动图在线制作网站有哪些,滑动动图图集怎么做?  历史网站制作软件,华为如何找回被删除的网站?  猪八戒网站制作视频,开发一个猪八戒网站,大约需要多少?或者自己请程序员,需要什么程序员,多少程序员能完成?  如何快速搭建自助建站会员专属系统?  家庭建站与云服务器建站,如何选择更优?  建站之星伪静态规则如何正确配置?  如何用好域名打造高点击率的自主建站?  公司门户网站制作公司有哪些,怎样使用wordpress制作一个企业网站?  如何选择香港主机高效搭建外贸独立站?  网站网页制作专业公司,怎样制作自己的网页?  利用JavaScript实现拖拽改变元素大小  高性价比服务器租赁——企业级配置与24小时运维服务  如何快速生成凡客建站的专业级图册?  专业公司网站制作公司,用什么语言做企业网站比较好?  香港服务器网站推广:SEO优化与外贸独立站搭建策略  如何用已有域名快速搭建网站?  大同网页,大同瑞慈医院官网?  网站制作难吗安全吗,做一个网站需要多久时间? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。