在 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 有值?

  1. 使用场景不同:$slots 主要用于普通插槽,而 $scopedSlots 用于作用域插槽。如果你的组件中只使用了作用域插槽,那么 $slots(特别是针对该作用域插槽的)可能没有值,而 $scopedSlots 会有值。
  2. 数据传递:作用域插槽允许你从子组件向插槽传递数据,这些数据在插槽的模板中可用。这种数据传递机制是通过 $scopedSlots 实现的,而不是 $slots。
  3. Vue 版本:确保你正在使用的 Vue 版本支持作用域插槽和 $scopedSlots。这个功能是从 Vue 2.6.0+ 版本开始引入的。
  4. 检查模板:确保你的模板中正确地使用了作用域插槽的语法(即 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 自动处理了参数的传递)来渲染插槽内容。


JHCan333
10 声望2 粉丝