插槽(Slot)是Vue中一种强大的内容分发机制,它允许你在组件中定义可替换的内容区域,为组件提供了更高的灵活性和可复用性。本文将全面介绍Vue插槽的各种用法。
1. 基本插槽
基本插槽是最简单的插槽形式,它允许父组件向子组件插入内容。
子组件定义插槽:
<!-- ChildComponent.vue -->
<template>
<div class="child">
<h2>子组件标题</h2>
<slot></slot> <!-- 插槽位置 -->
<p>子组件底部内容</p>
</div>
</template>
父组件使用:
<template>
<ChildComponent>
<p>这是插入到子组件中的内容</p>
</ChildComponent>
</template>
2. 后备内容(默认内容)
插槽可以设置默认内容,当父组件没有提供内容时显示。
<!-- ChildComponent.vue -->
<template>
<button type="submit">
<slot>提交</slot> <!-- 默认显示"提交" -->
</button>
</template>
3. 具名插槽
当一个组件需要多个插槽时,可以使用具名插槽。
子组件定义:
<!-- BaseLayout.vue -->
<template>
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot> <!-- 默认插槽,没有name属性 -->
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
</template>
父组件使用:
<template>
<BaseLayout>
<template v-slot:header>
<h1>这里是页眉</h1>
</template>
<p>这里是主内容,会放入默认插槽</p>
<template v-slot:footer>
<p>这里是页脚</p>
</template>
</BaseLayout>
</template>
4. 作用域插槽
作用域插槽允许子组件向插槽传递数据,父组件可以决定如何渲染这些数据。
子组件定义:
<!-- TodoList.vue -->
<template>
<ul>
<li v-for="(item, index) in items" :key="index">
<slot :item="item" :index="index"></slot>
</li>
</ul>
</template>
<script>
export default {
data() {
return {
items: ['吃饭', '睡觉', '写代码']
}
}
}
</script>
父组件使用:
<template>
<TodoList>
<template v-slot:default="slotProps">
<span v-if="slotProps.index % 2 === 0">✓</span>
{{ slotProps.item }}
</template>
</TodoList>
</template>
5. 解构插槽Prop
在作用域插槽中,可以使用ES6解构语法简化代码:
<template>
<TodoList>
<template v-slot:default="{ item, index }">
<span v-if="index % 2 === 0">✓</span>
{{ item }}
</template>
</TodoList>
</template>
6. 动态插槽名
插槽名可以是动态的:
<template>
<base-layout>
<template v-slot:[dynamicSlotName]>
...
</template>
</base-layout>
</template>
<script>
export default {
data() {
return {
dynamicSlotName: 'header'
}
}
}
</script>
7. 缩写语法
Vue提供了插槽的缩写语法:
v-slot:header
可以简写为#header
默认插槽
v-slot:default
可以简写为v-slot
或#default
<template>
<BaseLayout>
<template #header>
<h1>页眉</h1>
</template>
<template #default>
<p>主内容</p>
</template>
<template #footer>
<p>页脚</p>
</template>
</BaseLayout>
</template>
8. 高级用法:插槽函数
插槽可以像函数一样使用,实现更灵活的内容分发:
子组件:
<template>
<div>
<slot :user="user" :isLoggedIn="isLoggedIn"></slot>
</div>
</template>
<script>
export default {
data() {
return {
user: { name: '张三', age: 30 },
isLoggedIn: true
}
}
}
</script>
父组件:
<template>
<UserComponent>
<template v-slot="{ user, isLoggedIn }">
<div v-if="isLoggedIn">
欢迎, {{ user.name }}! 您已经{{ user.age }}岁了。
</div>
<div v-else>
请登录
</div>
</template>
</UserComponent>
</template>
总结
Vue插槽提供了强大的内容分发机制,通过基本插槽、具名插槽、作用域插槽等特性,可以创建高度可复用和灵活的组件。掌握插槽的使用可以显著提升Vue组件的开发效率和可维护性。
在实际开发中,插槽常用于构建布局组件、高阶组件(HOC)、列表渲染等场景,是Vue组件化开发的重要工具之一。