【Vue3】插槽slot
Vue3 插槽
父组件向子组件提前挖好的坑(slot)处,填入对应的内容就叫插槽。插入的内容不局限于文本,甚至可以传入多个元素和数组。
一、理解插槽
如何使用插槽
插槽使用的最多的地方就是使用ui组件库时
官网上的例子很好,用js的函数来类比。
// 父元素传入插槽内容
FancyButton('Click me!')
// FancyButton 在自己的模板中渲染插槽内容
function FancyButton(slotContent) {
return `<button class="fancy-btn">
${slotContent}
</button>`
}
渲染作用域
父组件模板中的表达式只能访问父组件的作用域;子组件模板中的表达式只能访问子组件的作用域。这和 JavaScript 的词法作用域规则是一致的。
二、默认插槽
// 父组件
<FancyButton>
Click me! <!-- 插槽内容 -->
</FancyButton>
// FancyButton子组件
<button class="fancy-btn">
<slot>我是默认值</slot> <!-- 父组件的插槽内容处缺省时,此处将会显示 -->
</button>
三、具名插槽和匿名插槽
<!-- 父组件中引入子组件container -->
<container>
<!-- 完整写法<template v-slot:header>,使用#替换v-slot: -->
<template #header>
<h1>header具名插槽的内容</h1>
</template>
<!-- 匿名插槽的内容 -->
<template #default> // 这行可以去掉
<p>默认插槽的内容1</p>
<p>默认插槽的内容2</p>
</template> // 这行可以去掉
<template #footer>
<p>footer具名插槽的内容</p>
</template>
</container>
<!-- 子组件container -->
<div class="container">
<div>
<!-- 名为header的具名插槽 -->
<slot name="header"></slot>
</div>
<div>
<!-- 匿名插槽 -->
<slot></slot>
</div>
<div>
<!-- 名为footer的具名插槽 -->
<slot name="footer"></slot>
</div>
</div>
四、动态插槽
<base-layout>
<template v-slot:[dynamicSlotName]>
...
</template>
<!-- 缩写为 -->
<template #[dynamicSlotName]>
...
</template>
</base-layout>
五、作用域插槽
默认作用域插槽
由于插槽的作用域,父组件无法访问到子组件的属性,可以通过props传递值那样。不过不同的是,在子组件插槽中使用符号:向上传递。所以作用域插槽是一个反向的过程,是由子组件向父组件通信的过程。
// 父组件
<!-- 完整写法<FancyButton v-slot=""> , slotProps为定义的props名,可以任意取名 -->
<FancyButton #="slotProps">
{{slotProps.text}} {{slotProps.num}}
</FancyButton>
// FancyButton子组件
<button class="fancy-btn">
<slot :text="刘慈欣:单走一个6" :num=6></slot>
</button>
具名作用域插槽
为什么默认作用域插槽和具名作用域插槽要分开讲,因为使用的时候不能混起来。混导致作用域传递的props混乱
<!-- 父组件中引入子组件container -->
<container>
<template #header="{data}">
<h1>{{data.num}}</h1> // 666
</template>
<!-- 使用作用域,默认插槽不要缩写 -->
<template #default="{data}">
<p>{{data.age}}</p> // 18
</template>
<template #footer>
<p>footer具名插槽的内容</p>
</template>
</container>
<!-- 子组件container -->
<div class="container">
<div>
<!-- name是给具名插槽用的,不会传给父组件。 -->
<!-- 将数据result通过slot的名为data的props传递给父组件 -->
<slot name="header" :data="result" ></slot>
</div>
<div>
<!-- 这里的data由于作用域的原因不会上面具名插槽混起来的 -->
<slot :data="defaultResult"></slot>
</div>
<div>
<slot name="footer"></slot>
</div>
</div>
let result = ref({num:666})
let defaultResult = ref({age:18})
六、更多实战用法
请到elementplus组件中学习配合使用,例如table中表格大量的使用了插槽。在el-table组件中我们使用插槽动态的对某一列某一行改变样式改变内容。
洗尽铅华始见金,褪去浮华归本真
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南