在 Vue.js 中,$slots 和 $scopedSlots 是组件实例上用于访问插槽内容的两个属性,但它们各自有不同的用途和表现方式,特别是在处理作用域插槽(scoped slots)时。
$slots
$slots 是一个包含所有插槽内容的对象。对于普通插槽(即未定义 v-slot 属性的插槽),你可以通过 $slots.default 访问默认插槽的内容,对于具名插槽(即定义了 slot 属性的插槽),你可以通过 $slots.插槽名 来访问对应插槽的内容。
然而,$slots 主要用于访问普通插槽(非作用域插槽)的内容,并且它提供的插槽内容是一个 VNode 数组,表示渲染的虚拟 DOM 元素。
$scopedSlots
$scopedSlots 是 Vue 2.6.0+ 版本中引入的,用于处理作用域插槽(scoped slots)。作用域插槽允许你向插槽传递数据,这些数据可以在插槽的模板中被访问。
$scopedSlots 是一个对象,其键是插槽的名字(对于默认插槽,键是 default),值是一个函数。这个函数接收一个参数(通常是组件内部的状态或数据),并返回一个 VNode 或 VNode 数组,表示渲染的插槽内容。
为什么 $slots 无值而 $scopedSlots 有值?
- 使用场景不同:$slots 主要用于普通插槽,而 $scopedSlots 用于作用域插槽。如果你的组件中只使用了作用域插槽,那么 $slots(特别是针对该作用域插槽的)可能没有值,而 $scopedSlots 会有值。
- 数据传递:作用域插槽允许你从子组件向插槽传递数据,这些数据在插槽的模板中可用。这种数据传递机制是通过 $scopedSlots 实现的,而不是 $slots。
- Vue 版本:确保你正在使用的 Vue 版本支持作用域插槽和 $scopedSlots。这个功能是从 Vue 2.6.0+ 版本开始引入的。
- 检查模板:确保你的模板中正确地使用了作用域插槽的语法(即 v-slot:插槽名="slotProps" 或简写为 #插槽名="slotProps"),并且父组件正在使用该插槽。
示例
假设你有一个子组件 ChildComponent,它使用了一个作用域插槽:
<!-- ChildComponent.vue -->
<template>
<div>
<slot name="scopedSlot" :user="user"></slot>
</div>
</template>
<script>
export default {
data() {
return {
user: { name: 'Alice' }
}
}
}
</script>
在父组件中,你可以这样使用这个作用域插槽:
<!-- ParentComponent.vue -->
<template>
<child-component>
<template v-slot:scopedSlot="slotProps">
<p>{{ slotProps.user.name }}</p>
</template>
</child-component>
</template>
<script>
import ChildComponent from './ChildComponent.vue'
export default {
components: {
ChildComponent
}
}
</script>
在这个例子中,$slots.scopedSlot 将不会有值(或者根本不存在这个键),而 $scopedSlots.scopedSlot 将是一个函数,你可以通过调用这个函数并传入需要的参数(虽然在这个例子中 Vue 自动处理了参数的传递)来渲染插槽内容。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。