为什么 Vue 常规槽也可以在 this.$scopedSlots 中使用?

Jos*_*ang 4 javascript vue.js vue-component vuejs2 vuejs3

请参阅这个最小示例

测试.vue

<template>
  <div>
    <slot name="this_is_not_scoped_slots"/>
  </div>
</template>

<script >
import Vue from "vue";

export default Vue.extend({
  mounted() {
    console.log(Object.keys(this.$scopedSlots));
  }
});
</script>
Run Code Online (Sandbox Code Playgroud)

应用程序.vue

<template>
  <Test>
    <template #this_is_not_scoped_slots>But it shows in this.$scopedSlots</template>
  </Test>
</template>

<script>
import Test from "./Test.vue";

export default {
  components: {
    Test
  }
};
</script>
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,该控制台将注销["this_is_not_scoped_slots"]

为什么会发生这种情况?

Vue实例中有两个属性

  1. this.$slots
  2. this.$scopedSlots

这两者的行为确实不同:

  1. 如果您使用v-slot:my_scope_name="{ someValue }",则my_scope_name不会出现在this.$slots
  2. 但是,无论您定义什么,您的命名插槽将始终显示在this.$scopedSlots

为什么会发生这种情况?

我正在构建一个库,如果用户是否提供了命名插槽,我想要条件渲染,我是否应该始终使用它this.$scopedSlots来检测这些东西?

Bou*_*him 8

根据官方API

  1. ....
  2. 所有现在也都作为函数$slots公开。$scopedSlots如果您使用渲染函数,现在建议始终通过 访问插槽$scopedSlots,无论它们当前是否使用作用域。这不仅会使未来添加作用域的重构变得更简单,而且还可以简化您最终迁移到 Vue 3 的过程,其中所有插槽都将是函数。