单个插槽

只使用这个标签的话,可以将父组件放在子组件的内容,放到想让他显示的地方

具名插槽

将放在子组件里的不同html标签放在不同的位置
父组件在要分发的标签里添加 slot=’name’ 属性
子组件在对应分发的位置的slot标签里,添加name=’name’ 属性,
然后就会将对应的标签放在对应的位置了



案例地址:http://dotwe.org/vue/e639fd36e7af82cce248ef835fa5d761
<http://dotwe.org/vue/e639fd36e7af82cce248ef835fa5d761>
从案例里面知道, 可以多次定义具名slot的内容,内容会被按顺序append到插槽中。未指定slot值的元素会被append到匿名插槽中。

Vue slot 原理

在web-components中有slot的概念,
https://developers.google.com/web/fundamentals/web-components/shadowdom
<https://developers.google.com/web/fundamentals/web-components/shadowdom>。

<slot> 元素
Shadow DOM 使用 <slot> 元素将不同的 DOM 树组合在一起。Slot 是组件内部的占位符,用户可以使用自己的标记来填充。

通过定义一个或多个 slot,您可将外部标记引入到组件的 shadow DOM 中进行渲染。 这相当于您在说“在此处渲染用户的标记”。

注:Slot 是为网络组件创建“声明性 API”的一种方法。它们混入到用户的 DOM 中,帮助对整个组件进行渲染,从而将不同的 DOM 树组合在一起。

如果 <slot> 引入了元素,则这些元素可“跨越” shadow DOM 的边界。 这些元素称为分布式节点。从概念上来看,分布式节点似乎有点奇怪。
Slot 实际上并不移动 DOM;它们在 shadow DOM 内部的其他位置进行渲染。

组件可在其 shadow DOM 中定义零个或多个 slot。Slot 可以为空,或者提供回退内容。 如果用户不提供 light DOM 内容,slot
将对其备用内容进行渲染。
<!-- Default slot. If there's more than one default slot, the first is used.
--> <slot></slot> <slot>Fancy button</slot> <!-- default slot with fallback
content --> <slot> <!-- default slot entire DOM tree as fallback --> <h2>Title</
h2> <summary>Description text</summary> </slot>
您还可以创建已命名 slot。已命名 slot 是 shadow DOM 中用户可通过名称引用的特定槽。

例如 - <fancy-tabs> shadow DOM 中的已命名 slot:
#shadow-root <div id="tabs"> <slot id="tabsSlot" name="title"></slot> </div> <
div id="panels"> <slot id="panelsSlot"></slot> </div> 组件用户对 <fancy-tabs> 的声明类似于:
<fancy-tabs> <button slot="title">Title</button> <button slot="title" selected>
Title 2</button> <button slot="title">Title 3</button> <section>content panel 1
</section> <section>content panel 2</section> <section>content panel 3</section>
</fancy-tabs> <!-- Using <h2>'s and changing the ordering would also work! --> <
fancy-tabs> <h2 slot="title">Title</h2> <section>content panel 1</section> <h2
slot="title" selected>Title 2</h2> <section>content panel 2</section> <h2 slot=
"title">Title 3</h2> <section>content panel 3</section> </fancy-tabs>
而且如果您很好奇,您会发现扁平树看起来类似于:
<fancy-tabs> #shadow-root <div id="tabs"> <slot id="tabsSlot" name="title"> <
button slot="title">Title</button> <button slot="title" selected>Title 2</button
> <button slot="title">Title 3</button> </slot> </div> <div id="panels"> <slot
id="panelsSlot"> <section>content panel 1</section> <section>content panel 2</
section> <section>content panel 3</section> </slot> </div> </fancy-tabs>
注意,我们的组件可处理不同的配置,但是扁平的 DOM 树保持不变。 我们还可以从 <button> 切换到 <h2>。
编写此组件的目的在于处理不同类型的子项 - 如同<select> 一样。

通过vue的渲染过程,可以看出slot渲染的原理
vm对象的$slots 会存储组件的所有插槽的vdom, 主要通过解析children,如果子组件指定了插槽名,会将vdom push
到对应名称的数组中,否则会push到default的数组中。
// named slots should only be respected if the vnode was rendered in the //
same context. if ((child.context === context || child.fnContext === context) &&
data && data.slot !=null ) { const name = data.slot const slot = (slots[name]
|| (slots[name] = []))if (child.tag === 'template') { slot.push.apply(slot,
child.children || []) }else { slot.push(child) } } else { (slots.default ||
(slots.default = [])).push(child) }
具体可以参看vue源码中的resolve-slots过程


https://github.com/vuejs/vue/blob/dev/src/core/instance/render-helpers/resolve-slots.js#L17

<https://github.com/vuejs/vue/blob/dev/src/core/instance/render-helpers/resolve-slots.js#L17>

那么创建DOM的过程就可以通过名称拿到具体组件:
// 单个插槽(匿名插槽) this.$slots['default']; // 具名插槽 this.$slots[slotName]

友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:[email protected]
QQ群:637538335
关注微信