深入理解vue slot插槽

单个插槽

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

具名插槽

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

深入理解vue slot插槽_第1张图片

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

Vue slot 原理

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

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

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

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

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

组件可在其 shadow DOM 中定义零个或多个 slot。Slot 可以为空,或者提供回退内容。 如果用户不提供 light DOM 内容,slot 将对其备用内容进行渲染。


<slot>slot>

<slot>Fancy buttonslot> 

<slot> 
  <h2>Titleh2>
  <summary>Description textsummary>
slot>

您还可以创建已命名 slot。已命名 slot 是 shadow DOM 中用户可通过名称引用的特定槽。

例如 - 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">Titlebutton>
  <button slot="title" selected>Title 2button>
  <button slot="title">Title 3button>
  <section>content panel 1section>
  <section>content panel 2section>
  <section>content panel 3section>
fancy-tabs>


<fancy-tabs>
  <h2 slot="title">Titleh2>
  <section>content panel 1section>
  <h2 slot="title" selected>Title 2h2>
  <section>content panel 2section>
  <h2 slot="title">Title 3h2>
  <section>content panel 3section>
fancy-tabs>

而且如果您很好奇,您会发现扁平树看起来类似于:


<fancy-tabs>
  #shadow-root
    <div id="tabs">
      <slot id="tabsSlot" name="title">
        <button slot="title">Titlebutton>
        <button slot="title" selected>Title 2button>
        <button slot="title">Title 3button>
      slot>
    div>
    <div id="panels">
      <slot id="panelsSlot">
        <section>content panel 1section>
        <section>content panel 2section>
        <section>content panel 3section>
      slot>
    div>
fancy-tabs>

注意,我们的组件可处理不同的配置,但是扁平的 DOM 树保持不变。 我们还可以从