
插槽是什么
插槽是组件的内容分发机制。子组件在模板里放一个 <slot> 占位,父组件写在子组件标签里的内容就渲染到这个位置。
<!-- 子组件 Dialog.vue --><div class="dialog"> <slot></slot></div>默认插槽
<slot> 不写 name 时,它的名字隐含为 default,也就是默认插槽。
<Dialog> <div>我是填充的内容</div></Dialog>父组件标签里没有指定插槽名的顶层内容,都会进入默认插槽。
具名插槽
子组件需要多个内容出口时,给每个 <slot> 起 name,父组件按名字填充。
<!-- 子组件 --><div> <slot name="header"></slot> <slot></slot> <slot name="footer"></slot></div>父组件用 <template v-slot:xxx> 指定目标插槽,v-slot:xxx 对应子组件里 name="xxx" 的插槽,简写是 #。没有指定名字的内容落在默认插槽。
<Dialog> <template v-slot:header> <div>我是头部</div> </template>
<template v-slot:footer> <div>我是底部</div> </template>
<div>我是默认内容</div></Dialog>v-slot 放在哪里
v-slot 写在 <template> 上和写在组件上都行。写在组件上时,只支持单个默认作用域插槽:
<Mouse v-slot="{ x, y }"> Mouse position: {{ x }}, {{ y }}</Mouse>想同时用具名插槽和默认作用域插槽时,把 v-slot 放在组件上会编译报错,这时默认插槽要写成显式的 <template #default>。
v-slot 后面的参数可以省略,省略时指向 default,所以 <Child v-slot="{ x, y }"> 是合法的。只有要填充具名插槽时,才需要写名字。
作用域插槽
普通插槽只能读父组件的数据。作用域插槽让子组件在渲染时把自己内部的数据传出去,由父组件决定怎么显示。
子组件在 <slot> 上用 v-bind 绑数据:
<!-- 子组件 --><slot :data="item"></slot>这些绑定会打包成一个插槽 props 对象,父组件在 v-slot 的值上接收,可以直接解构:
<Dialog> <template #default="{ data }"> <div>{{ data }}</div> </template></Dialog>#default="props" 拿到的是整个对象,写成 #default="{ data }" 就只取需要的字段。
列表、表格、树形这类组件常用作用域插槽:子组件负责遍历和取数,父组件负责每一项怎么显示。
动态插槽名
插槽名可以是变量,用 #[slotName] 绑定:
<template> <Dialog> <template #[activeSlot]> <div>插到 {{ activeSlot }} 插槽</div> </template> </Dialog></template>
<script setup>import { ref } from 'vue'
const activeSlot = ref('header')</script>方括号里的表达式求值结果应当是字符串(也允许 null),否则匹配不到具名插槽。常见用法是按状态切换插槽。
插槽的默认内容
<slot> 标签里的内容就是默认内容,父组件没有提供对应内容时显示:
<slot> 我是默认内容,父组件没填时显示</slot>Vue 3 学习笔记
连载中分享文章
生成精美分享图或复制链接,与更多人分享本文。
继续阅读
换条路线
从其他文章中稳定抽取
最后更新于 ,距今已过 208 天
部分内容可能已过时