Vue2 插槽(Slot)核心总结
插槽是 Vue2 中实现组件内容灵活定制的核心机制,让父组件可以向子组件的指定位置插入自定义内容,解决了 “组件结构复用但内容需要动态变化” 的问题。
一、插槽的本质
- 子组件中通过
<slot>
标签预留 “占位符”,父组件使用子组件时,在子组件标签内编写的内容会自动替换到这些占位符位置。 - 核心价值:让组件既能保持结构复用,又能根据不同场景定制内容(比如通用弹窗、卡片组件,不同场景显示不同内容)。
二、三种插槽类型及用法
1. 默认插槽(匿名插槽)
- 特点:子组件中只有一个插槽,无需命名,父组件内容默认填充到这里。
- 子组件定义(
MyComponent.vue
):<template><div class="container"><!-- 默认插槽:无name属性,可写默认内容 --><slot>这是默认内容(没传内容时显示)</slot></div> </template>
- 父组件使用:
<template><!-- 父组件内容会替换子组件的slot --><MyComponent><p>这是父组件传入的自定义内容</p></MyComponent> </template>
2. 具名插槽(命名插槽)
- 特点:子组件有多个插槽,通过
name
属性区分不同位置,父组件需按名称对应填充。 - 子组件定义:
<template><div class="card"><!-- 头部插槽:name="header" --><slot name="header">默认头部</slot><!-- 内容插槽:默认插槽(等效于name="default") --><slot>默认内容</slot><!-- 底部插槽:name="footer" --><slot name="footer">默认底部</slot></div> </template>
- 父组件使用:
<template><MyComponent><!-- 填充头部插槽:v-slot:header 简写为 #header --><template #header><h2>卡片标题</h2></template><!-- 填充默认插槽:无需指定name --><p>这是卡片的具体内容</p><!-- 填充底部插槽 --><template #footer><button>操作按钮</button></template></MyComponent> </template>
3. 作用域插槽
- 特点:子组件向插槽传递数据,父组件接收数据后自定义渲染方式(解决 “子组件有数据,但父组件决定显示形式” 的场景)。
- 子组件定义(传递数据):
<template><div><!-- 子组件通过属性向插槽传数据(:items="list") --><slot :items="list" :title=" '列表标题' "></slot></div> </template> <script> export default {data() {return { list: ['Vue', 'React', 'Angular'] } // 子组件的数据} } </script>
- 父组件使用(接收并渲染数据):
<template><MyComponent><!-- 用#default="slotProps"接收子组件数据 --><template #default="slotProps"><h3>{{ slotProps.title }}</h3><!-- 自定义渲染:用列表展示 --><ul><li v-for="item in slotProps.items" :key="item">{{ item }}</li></ul></template></MyComponent> </template>
三、关键规则与注意事项
- 默认内容:
<slot>
标签内的内容为默认内容,父组件未传内容时显示。 - 简写语法:
v-slot:插槽名
可简写为#插槽名
(如v-slot:header
→#header
)。 - 作用域插槽数据:父组件通过
slotProps
(可自定义命名)接收子组件传递的所有数据,是一个包含所有传递属性的对象。 - template 的使用:
- 具名插槽和作用域插槽通常需要用
<template>
包裹内容,明确指定插槽名和接收数据。 - 默认插槽可省略
<template>
,直接在子组件标签内写内容。
- 具名插槽和作用域插槽通常需要用
四、使用场景总结
- 默认插槽:简单的单位置内容定制(如弹窗内容)。
- 具名插槽:多位置内容定制(如卡片的头部、内容、底部)。
- 作用域插槽:子组件数据需要父组件自定义渲染(如同一组数据,有时用列表、有时用表格展示)。
一句话概括:插槽是组件的 “内容接口”,让组件在复用的同时,保持内容的灵活性和定制化。