为什么 this.$scopedSlots 中也提供 Vue 常规插槽?

Why Vue regular slots also available in this.$scopedSlots?

请看这个最小的例子

Test.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>

App.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>

在上面的示例中,此控制台将注销 ["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 来检测这些东西吗?

根据 official API :

  1. ....
  2. All $slots are now also exposed on $scopedSlots as functions. If you work with render functions, it is now recommended to always access slots via $scopedSlots, whether they currently use a scope or not. This will not only make future refactors to add a scope simpler, but also ease your eventual migration to Vue 3, where all slots will be functions.