Vue.js 中的插槽(Slots)是Vue组件间进行内容传递的重要机制,用于在父组件中向子组件插入内容。以下是各类插槽的解释和用法:
-
匿名插槽 / 默认插槽:
- 当你在子组件中定义一个没有
name
属性的<slot>
标签时,它就是一个匿名插槽或默认插槽。 - 如果父组件没有明确指明要插入到哪个具名插槽,那么所有未分配的内容将自动填充到默认插槽中。
<!-- 子组件 --> <template><div><slot>这是默认插槽的默认内容</slot></div> </template><!-- 父组件 --> <MyComponent><p>这段文本会插入到子组件的默认插槽中</p> </MyComponent>
- 当你在子组件中定义一个没有
-
具名插槽:
- 具名插槽允许你为特定区域定义名称,父组件可以按照名称将内容插入到子组件的不同位置。
<!-- 子组件 --> <template><div><h2><slot name="header"></slot></h2><slot name="body"></slot><footer><slot name="footer"></slot></footer></div> </template><!-- 父组件 --> <MyComponent><template v-slot:header><h3>这是页头</h3></template><template v-slot:body><p>这是主体内容</p></template><template v-slot:footer><p>这是页脚</p></template> </MyComponent>
-
作用域插槽( Scoped Slots):
- 作用域插槽允许子组件向其插槽传递数据,让父组件可以在插槽内容中访问这些数据。
- 在 Vue 2.x 中使用
slot-scope
特性实现,在 Vue 3.x 中使用v-slot
指令及其参数语法实现。
<!-- Vue 2.x --> <!-- 子组件 --> <template><ul><li v-for="item in items"><slot :item="item" slot-scope="{ item }">{{ item.text }}</slot></li></ul> </template><!-- 父组件 --> <MyListComponent><template slot="default" slot-scope="{ item }"><strong>{{ item.title }}</strong>: {{ item.description }}</template> </MyListComponent><!-- Vue 3.x --> <!-- 子组件 --> <script setup> const items = [/*...*/]; </script> <template><ul><li v-for="item in items"><slot :item="item">{{ item.text }}</slot></li></ul> </template><!-- 父组件 --> <MyListComponent><template #default="{ item }"><strong>{{ item.title }}</strong>: {{ item.description }}</template> </MyListComponent>
-
插槽默认值:
- 子组件可以为其插槽定义默认内容,当父组件没有提供相应插槽内容时,这个默认内容将会被展示出来。
- 在上面匿名插槽的例子中,“这是默认插槽的默认内容”就是默认值。
<!-- Vue 2.x -->
<!-- 子组件 -->
<template><ul><li v-for="item in items"><slot :item="item" slot-scope="{ item }">{{ item.text }}</slot></li></ul>
</template><!-- 父组件 -->
<MyListComponent><template slot="default" slot-scope="{ item }"><strong>{{ item.title }}</strong>: {{ item.description }}</template>
</MyListComponent><!-- Vue 3.x -->
<!-- 子组件 -->
<script setup>
const items = [/*...*/];
</script>
<template><ul><li v-for="item in items"><slot :item="item">{{ item.text }}</slot></li></ul>
</template><!-- 父组件 -->
<MyListComponent><template #default="{ item }"><strong>{{ item.title }}</strong>: {{ item.description }}</template>
</MyListComponent>