Vue3 插槽 <slot>
在 Vue3 中,插槽(slot)是一种让父组件向子组件传递内容的机制。你可以将插槽理解为子组件中预留的"占位符",父组件可以在这些占位符中插入任意内容。这样,子组件就可以在不改变自身结构的情况下,灵活地展示父组件传递的内容。
插槽的基本用法
默认插槽
默认插槽是最简单的插槽类型。在子组件中,你可以使用 <slot>
标签来定义一个默认插槽。父组件在使用子组件时,可以在这个插槽中插入内容。
实例
<!-- 子组件 ChildComponent.vue -->
<template>
<div class="child">
<h3>这是子组件的标题</h3>
<slot>默认内容</slot>
</div>
</template>
<template>
<div class="child">
<h3>这是子组件的标题</h3>
<slot>默认内容</slot>
</div>
</template>
实例
<!-- 父组件 ParentComponent.vue -->
<template>
<ChildComponent>
<p>这是父组件传递的内容</p>
</ChildComponent>
</template>
<template>
<ChildComponent>
<p>这是父组件传递的内容</p>
</ChildComponent>
</template>
在父组件中,我们可以在 <ChildComponent>
标签内插入内容,这些内容将会替换子组件中的 <slot>
标签。如果父组件没有传递内容,子组件会显示 <slot>
标签内的默认内容。
具名插槽
具名插槽允许你在子组件中定义多个插槽,并通过名称来区分它们。在父组件中,你可以使用 v-slot
指令来指定要插入哪个插槽。
实例
<!-- 子组件 ChildComponent.vue -->
<template>
<div class="child">
<header>
<slot name="header">默认头部内容</slot>
</header>
<main>
<slot>默认主体内容</slot>
</main>
<footer>
<slot name="footer">默认底部内容</slot>
</footer>
</div>
</template>
<template>
<div class="child">
<header>
<slot name="header">默认头部内容</slot>
</header>
<main>
<slot>默认主体内容</slot>
</main>
<footer>
<slot name="footer">默认底部内容</slot>
</footer>
</div>
</template>
实例
<!-- 父组件 ParentComponent.vue -->
<template>
<ChildComponent>
<template v-slot:header>
<h1>自定义头部内容</h1>
</template>
<p>这是父组件传递的主体内容</p>
<template v-slot:footer>
<p>自定义底部内容</p>
</template>
</ChildComponent>
</template>
<template>
<ChildComponent>
<template v-slot:header>
<h1>自定义头部内容</h1>
</template>
<p>这是父组件传递的主体内容</p>
<template v-slot:footer>
<p>自定义底部内容</p>
</template>
</ChildComponent>
</template>
在上面的例子中,我们定义了三个插槽:header
、main
(默认插槽)和 footer
。父组件通过 v-slot
指令将内容插入到对应的插槽中。
作用域插槽
作用域插槽允许子组件向父组件传递数据,父组件可以根据这些数据来渲染内容。这在需要定制子组件内部渲染逻辑时非常有用。
基本用法
在子组件中,你可以通过 v-bind
将数据传递给插槽。父组件则可以通过 v-slot
指令接收这些数据。
实例
<!-- 子组件 ChildComponent.vue -->
<template>
<div class="child">
<slot :user="user"></slot>
</div>
</template>
<script>
export default {
data() {
return {
user: { name: 'Alice', age: 25 }
};
}
};
</script>
<template>
<div class="child">
<slot :user="user"></slot>
</div>
</template>
<script>
export default {
data() {
return {
user: { name: 'Alice', age: 25 }
};
}
};
</script>
实例
<!-- 父组件 ParentComponent.vue -->
<template>
<ChildComponent v-slot="{ user }">
<p>用户名称:{{ user.name }}</p>
<p>用户年龄:{{ user.age }}</p>
</ChildComponent>
</template>
<template>
<ChildComponent v-slot="{ user }">
<p>用户名称:{{ user.name }}</p>
<p>用户年龄:{{ user.age }}</p>
</ChildComponent>
</template>
在这个例子中,子组件通过 v-bind
将 user
对象传递给插槽,父组件通过 v-slot="{ user }"
接收这个对象,并根据 user
的数据渲染内容。