Vue 插槽 Slot — 组件内容分发
学习Vue插槽机制:默认插槽、具名插槽、作用域插槽 · 难度:进阶 · +20XP
什么是插槽?
插槽(Slot)让组件可以接收外部传入的HTML内容,渲染到组件内部的指定位置。
想象一个"卡片"组件——它的框架是固定的(圆角边框、阴影),但里面的内容每次都不一样。插槽就是解决这个问题的。
默认插槽
组件内部放一个 <slot> 标签作为"出口",外部内容就渲染到这里:
<!-- 子组件模板 -->
<div class="card">
<div class="card-body">
<slot></slot> <!-- 这里放外部传进来的内容 -->
</div>
</div>
<!-- 父组件使用 -->
<my-card>
<h3>标题</h3>
<p>这是卡片的正文内容</p>
</my-card>
也可以给插槽设置默认内容——如果父组件没传内容,就显示默认的:
<slot>这是默认内容,没人传我就显示这个</slot>
具名插槽(Named Slots)
当一个组件需要多个插槽出口时,给每个插槽起个名字:
<!-- 子组件:布局组件 -->
<div class="layout">
<header><slot name="header"></slot></header>
<main><slot></slot></main> <!-- 默认插槽 -->
<footer><slot name="footer"></slot></footer>
</div>
<!-- 父组件:用 v-slot 指定内容去哪个插槽 -->
<page-layout>
<template v-slot:header>
<h1>页面标题</h1>
</template>
<p>这是默认插槽的内容</p>
<template v-slot:footer>
<small>版权 © 2024</small>
</template>
</page-layout>
简写:v-slot:header 可以写成 #header
作用域插槽(Scoped Slots)
这是最强大的插槽:子组件把数据传给父组件,父组件决定怎么渲染。
<!-- 子组件:暴露数据 -->
<ul>
<li v-for="item in items" :key="item.id">
<slot name="item" :item="item">
{{ item.name }} <!-- 默认渲染 -->
</slot>
</li>
</ul>
<!-- 父组件:自定义渲染 -->
<todo-list :items="todos">
<template #item="{ item }">
<span style="color:blue">{{ item.name }}</span>
<button @click="remove(item.id)">删除</button>
</template>
</todo-list>
动手试试
右边演示了默认插槽的用法——卡片组件的框架是固定的,内容由外部传入。