我有一个列表和一个 list_item 组件,我在应用程序中多次重复使用它们。简化形式:
contact_list.vue
<template lang="pug">
.table
.table-header.table-row
.table-col Contact
.table-col Info
.table-body
contact-list-item(v-for='contact in contacts',
:contact='contact',
@click='doSomething()')
</template>
contact_list_item.vue
<template lang="pug">
.table-row(@click='emitClickEvent')
.table-col {{ contact.name }}
.table-col {{ contact.info }}
</template>
当我在特定组件中使用 contact_list 时,我希望能够发送一个槽,将一些新列添加到 contact_list_item 组件中。此槽将使用在 contact_list_item 组件内呈现的特定联系人的数据来生成新列。
我怎样才能做到这一点?使用插槽是最好的方法吗?
提前致谢。
插槽是最好的方法,您需要为
contact-list-item
组件使用作用域插槽。我不太熟悉 pug,所以我将使用 HTML 作为示例。
在
contact-list
中,您将添加一个插槽。请注意,在这种情况下,联系人将作为属性传递。这样我们就可以利用作用域插槽。
<div class="table">
<div class="table-header table-row">
<div class="table-col">Contact</div>
<div class="table-col">Info</div>
</div>
<div class="table-body">
<contact-list-item v-for='contact in contacts'
:contact="contact"
@click="doSomething"
:key="contact.id">
<slot :contact="contact"></slot>
</contact-list-item>
</div>
</div>
然后向
contact-list-item
添加一个插槽。
<div class="table-row" @click="emitClickEvent">
<div class="table-col">{{contact.name}}</div>
<div class="table-col">{{contact.info}}</div>
<slot></slot>
</div>
最后,在您的 Vue 模板中,使用作用域模板。
<div id="app">
<contact-list :contacts="contacts">
<template scope="{contact}">
<div class="table-col">{{contact.id}}</div>
</template>
</contact-list>
</div>
这是一个工作示例。我不知道您的样式是什么,但请注意
id
列现在显示在 contact-list-item
中。
您可以使用
template
将插槽注册到子组件的子组件。
还有一种情况是你想要有很多命名槽。
child.vue
<template>
<div>
<h2>I'm a father now</h2>
<grandchild :babies="babies">
<template v-for="(baby, id) in babies" :slot="baby.name">
<slot :name="baby.name"/>
</template>
</grandchild>
</div>
</template>
孙子.vue
<template>
<div>
<p v-for="(baby, id) in babies" :key="id">
<span v-if="baby.isCry">Owe...owe...</span>
<slot :name="baby.name">
</p>
</div>
</template>
parent.vue
<template>
<div>
<h2>Come to grandpa</h2>
<child :babies="myGrandChilds">
<button slot="myGrandChilds[2].name">baby cry</button>
</child>
</div>
</template>
添加到@DrSensor的答案。
在Vue3中,你应该使用动态槽名称。
<template>
<div>
<h2>I'm a father now</h2>
<grandchild :babies="babies">
<template v-for="(baby, id) in babies" #[baby.name]>
<slot :name="baby.name"/>
</template>
</grandchild>
</div>
</template>
这里是一个使用 Vuetify Playground 的示例演示 Vue 3 动态槽/模板传递:
<template #[name] v-for="slot, name in $slots">
<slot :name="name"></slot>
</template>
为了方便的将几个槽位往下平移,可以使用这个链接描述的方法,稍微修改一下,也许就能往更深的方向移动。