Vuejs 中的嵌套 "bi-directional" 个插槽

Nested "bi-directional" slots in Vuejs

我正在使用 Vuejs。 我创建了两个组件:FirstSecond.

  1. First 呈现 Second.
  2. Second 有一个命名槽。
  3. First 包含一个 <template>,进入 Second 的命名槽。
  4. First<template> 内 - 还有另一个命名插槽。
  5. Second<slot> 中 - 有一个 <template>,用于进入 First<template> 的命名槽。

我得到的是 First<template>Second 的插槽中呈现。

这是正确的,但我还想看到 Second<template>First<template><slot> 中呈现。但是我没有。

代码如下:

var First = Vue.extend({
  template: `
    <div>
      In first<br/>
      <second>
        <template slot="slot1">
          In template of First
          <slot name="slot2">
          </slot>
        </template>
      </second>
    </div>
  `
})
Vue.component('first', First)

var Second = Vue.extend({
  template: `
    <div>
      In second<br/>
      <slot name="slot1">
        <template slot="slot2">
          In template of Second
        </template>
      </slot>
    </div>
  `
})
Vue.component('second', Second)

这是输出:

In first
In second
In template of First

这是 jsfiddle:https://jsfiddle.net/obeobe/f98kr4ye/

我想得到这个输出:

In first
In second
In template of First
In template of Second

我可以用插槽实现吗?如果不是,是否可以通过其他方式实现,但不创建第三个组件?

编辑:一个可能的现实生活用例:一个列表组件,允许每个项目的 HTML 内容由其主机定义,并且可以在宿主指定的位置,在宿主的内容中注入它自己的一些内容。

例如,像这样:

主机组件:

<div class="myList">
    <list v-bind:items="usersArray">
        <template slot="itemSlot" slotScope="item">
            <div>{{ item.name }}</div>
            <div>{{ item.country }}</div>
            <div>{{ item.phone }}</div>
            <slot name="actions"> <--------- the spot for the List component to inject generic actions
            </slot>
            <div>{{ item.age }}</div>
        </template>
    </list>
</div>

"List"分量:

<div>
    <div v-for="(anItem, idx) in items">
        <div>{{ idx }}</div>
        <slot name="itemSlot" v-bind:item="anItem">
            <template slot="actions">
                <a v-on:click="duplicateItem(anItem)">Duplicate</a> <---------- the "duplicateItem" method would be implemented inside this List component
                <a>Edit</a>
                <a>Delete</a>
            </template>
        </slot>
    </div>
</div>

据我所知,Vue.js

中没有双向插槽
<div id="app">
  <first>
         ─────────────────────┐
  </first>                    │
</div>                        │
                              │
<div>                         │
  In first<br/>               │
  <second>                    │
    <template slot="slot1">  ─────┐
      In template of First    │   │
      <slot name="slot2">  <──┘ ┄┄│┄┄> This slot will replaced by slot2
      </slot>                     │    template child of first component.
    </template>                   │
  </second>                       │
</div>                            │
                                  │
<div>                             │
  In second<br/>                  │
  <slot name="slot1">  <──────────┘
    <template slot="slot2">  ┄┄┄┄┄┄┄┄> This is fallback content it will 
      In template of Second            shows up if no content provided.
    </template>                        But slot template is used so
                                       this will go to replace slot2
                                       inside slot.
  </slot>
</div>

由于 slot2slot 组件内没有定义任何插槽,因此您的 In template of Second 永远不会出现。

在你的例子中我认为没有办法实现。另一种实现方式是通过插槽作用域绑定 duplicateItem

<div class="myList">
  <list v-bind:items="usersArray">
    <template slot="itemSlot" slotScope="{ item, duplicateItem }">
      <div>{{ item.name }}</div>
      <div>{{ item.country }}</div>
      <div>{{ item.phone }}</div>
      <div>
        <a v-on:click="duplicateItem(item)">Duplicate</a>
        <a>Edit</a>
        <a>Delete</a>
      </div>
      <div>{{ item.age }}</div>
    </template>
  </list>
</div>

<div>
  <div v-for="(anItem, idx) in items">
    <div>{{ idx }}</div>
      <slot name="itemSlot"
        v-bind:item="anItem"
        v-bind:duplicateItem="duplicateItem">
      </slot>
    </div>
  </div>
</div>