Vuejs 中的嵌套 "bi-directional" 个插槽
Nested "bi-directional" slots in Vuejs
我正在使用 Vuejs。
我创建了两个组件:First
和 Second
.
First
呈现 Second
.
Second
有一个命名槽。
First
包含一个 <template>
,进入 Second
的命名槽。
- 在
First
的 <template>
内 - 还有另一个命名插槽。
- 在
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>
由于 slot2
或 slot
组件内没有定义任何插槽,因此您的 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>
我正在使用 Vuejs。
我创建了两个组件:First
和 Second
.
First
呈现Second
.Second
有一个命名槽。First
包含一个<template>
,进入Second
的命名槽。- 在
First
的<template>
内 - 还有另一个命名插槽。 - 在
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>
由于 slot2
或 slot
组件内没有定义任何插槽,因此您的 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>