在 Vue 中,slot
是一种用于分发内容的机制,它允许父组件向子组件传递内容,而子组件通过插槽来接收和渲染这些内容。slot
可以用于创建更加灵活和可复用的组件。它的工作原理类似于 HTML 中的插入点,允许将父组件的内容传递给子组件进行渲染。
一、基本插槽
最基本的插槽用法是父组件向子组件传递内容,子组件通过 <slot></slot>
标签来接收和渲染这些内容。
1. 基本插槽示例
<!-- ParentComponent.vue -->
<template>
<div>
<ChildComponent>
<p>这是父组件传递给子组件的内容</p>
</ChildComponent>
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent
}
};
</script>
<!-- ChildComponent.vue -->
<template>
<div>
<h2>子组件内容</h2>
<slot></slot> <!-- 渲染父组件传递的内容 -->
</div>
</template>
<script>
export default {
name: 'ChildComponent'
};
</script>
在上面的例子中,父组件通过 <ChildComponent>
标签向子组件传递一个 <p>
元素的内容。子组件通过 <slot></slot>
来接收并渲染父组件的内容。
二、具名插槽
具名插槽允许我们为插槽命名,从而在父组件中更精确地控制哪些内容传递到哪个插槽。
1. 具名插槽示例
<!-- ParentComponent.vue -->
<template>
<div>
<ChildComponent>
<template v-slot:header>
<h1>这是父组件传递给header插槽的内容</h1>
</template>
<template v-slot:footer>
<p>这是父组件传递给footer插槽的内容</p>
</template>
</ChildComponent>
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent
}
};
</script>
<!-- ChildComponent.vue -->
<template>
<div>
<div class="header">
<slot name="header"></slot> <!-- 渲染传递给header的内容 -->
</div>
<div class="footer">
<slot name="footer"></slot> <!-- 渲染传递给footer的内容 -->
</div>
</div>
</template>
<script>
export default {
name: 'ChildComponent'
};
</script>
在这个示例中,父组件将内容分别传递给 header
和 footer
这两个具名插槽。子组件通过 <slot name="header"></slot>
和 <slot name="footer"></slot>
来渲染这些内容。
三、作用域插槽(Scoped Slots)
作用域插槽允许父组件向子组件传递内容的同时,子组件也可以向父组件暴露一些数据或方法,这样父组件可以使用子组件的数据来渲染内容。通过作用域插槽,父组件可以获取子组件中的数据。
1. 作用域插槽示例
<!-- ParentComponent.vue -->
<template>
<div>
<ChildComponent v-slot:default="slotProps">
<p>{{ slotProps.message }}</p>
</ChildComponent>
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent
}
};
</script>
<!-- ChildComponent.vue -->
<template>
<div>
<slot :message="message"></slot> <!-- 向父组件暴露数据 -->
</div>
</template>
<script>
export default {
data() {
return {
message: '这是来自子组件的数据'
};
}
};
</script>
在上面的例子中,子组件通过 slot
向父组件暴露一个 message
数据,父组件通过 v-slot:default="slotProps"
获取这个数据,并在模板中使用它。slotProps
包含了子组件传递给父组件的所有数据。
四、插槽的 v-bind
和默认内容
插槽也可以通过 v-bind
将数据传递给子组件,子组件可以使用传递的数据进行渲染。同时,我们还可以为插槽指定默认内容,在没有传递内容时显示默认内容。
1. 使用 v-bind
和默认插槽内容
<!-- ParentComponent.vue -->
<template>
<div>
<ChildComponent>
<template v-slot:default="slotProps">
<p>{{ slotProps.text }}</p>
</template>
</ChildComponent>
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent
}
};
</script>
<!-- ChildComponent.vue -->
<template>
<div>
<slot :text="message"></slot> <!-- 向父组件暴露数据 -->
</div>
</template>
<script>
export default {
data() {
return {
message: 'Hello from child component!'
};
}
};
</script>
在这个例子中,子组件通过 slot
向父组件传递 message
数据,父组件通过 v-slot
获取并使用它。父组件渲染出 message
内容。
2. 默认内容
如果父组件没有传递插槽内容,子组件可以使用默认内容。
<!-- ParentComponent.vue -->
<template>
<ChildComponent>
<!-- 如果没有传递内容,则显示默认内容 -->
<template v-slot:default>
<p>这是父组件提供的默认内容</p>
</template>
</ChildComponent>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent
}
};
</script>
<!-- ChildComponent.vue -->
<template>
<div>
<slot>这是子组件的默认内容</slot> <!-- 默认内容 -->
</div>
</template>
在这个例子中,如果父组件没有传递内容给插槽,则 ChildComponent
会使用默认的插槽内容。
五、总结
- 基本插槽:通过
<slot></slot>
标签将父组件的内容传递给子组件。 - 具名插槽:使用
name
属性为插槽命名,从而指定父组件的不同内容传递到不同的插槽中。 - 作用域插槽:允许父组件访问子组件暴露的数据,从而更灵活地控制插槽内容。
v-bind
和默认内容:可以通过v-bind
向插槽传递数据,并为插槽设置默认内容。
slot
是 Vue 中非常强大的功能,它使得组件更加灵活和可复用,帮助我们更高效地构建 UI 组件。