具名插槽和作用域插槽

1,292 阅读1分钟

具名插槽

1、如果想要获取子组件标签之间的值该怎么办呢?

<!-- 子组件 my-son -->
<div>
    <slot></slot>
</div>
<!-- 父组件 -->
<div>
    <my-son>哇哈哈</my-son>
</div>
  • 可以通过 this.$slots 拿到所有内容
  • 可以通过 this.$slots 拿到虚拟节点(VNode)
  • 可以通过 this.$slots.default[0].text 来拿到具体的值(哇哈哈)
  • 这在造轮子的时候很好用

2、如果更为复杂的结构呢?

<!-- 父组件 -->
<div>
    <my-son>
        <h1>标题</h1>
        <p>内容内容...</p>
        <template v-slot:hideContent>
            <p>隐藏...</p>
        </template>
        哇哈哈
    </my-son>
</div>
  • 子组件可以通过 this.$slots 拿到所有子组件标签(<my-son></my-son>)之间的所有内容

  • this.$slots 打印出来包括 default 、hideContent

    • default 是一个数组,包括所有未被 v-slot 命名的内容 h1 、 p 、哇哈哈
    • hideContent 相当于从 default 中抽离出来,并且与它同级
  • 类似于 哇哈哈 这种不套标签的,可以直接通过 this.$slots.default[2].text 拿到值,而像<h1>标题</h1>带标签的,则需要通过 this.$slots.default[0].children[0].text 拿到值标题

补充

  • v-slot 只能添加在 <template></template> 上,并且标签之间的内容不会被展示
  • this.$slots.default 可以在 created 中获取,而 this.$slots.hideContent 在 mounted 中才能拿到
  • 子组件即使没有<slot></slot>标签 也可以通过 this.$slots 拿到标签之间的内容,只是不会展示在页面上

作用域插槽:子组件通过slot传值

假设有子组件里的 data 想要通过 slot 的方式传值给父组件该怎么办?

<!-- 子组件 -->
<template>
  <div>
    <slot>
      {{user.firstName}}    <!-- small -->
    </slot>
  </div>
</template><script>
export default {
  name: "my-son",
  data(){
    return{
      user:{
        firstName:'small',
        lastName:'dog'
      }
    }
  },
</script>
<!-- 父组件 -->
<template>
  <div>
    <my-son>
      {{user.lastName}} <!-- ERROR -->
    </my-son>
  </div>
</template>

父组件也想通过 user.lastName 的方式获取到user对象里的值,user 作为子组件的数据,直接在父组件使用显然会报错。

为了让 user 在父组件的插槽中使用,可以在子组件中进行绑定。

<!-- 子组件 -->
<div>
    <slot :user="user">
        {{user.firstName}}  <!-- small -->
    </slot>
</div>

绑定在<slot></slot>标签上的属性被称为插槽prop,可以在父组件中使用带值的v-slot来定义我们自己提供的插槽 slot 的名字

<div>
    <my-son v-slot:default="slotProps">
        {{slotProps.user.lastName}} <!-- dog -->
    </my-son>
</div>