简单解读vue中的slot插槽

81 阅读1分钟

slot插槽种类

  • 默认插槽
  • 具名插槽
  • 作用域插槽

默认插槽

父组件:

<template>
    <div class="container">
        <h3>这里是父组件</h3>
        <child>
            <div class="test">
              <span>testOne</span>
            </div>
        </child>
    </div>
</template>

子组件:child

<template>
    <div class="child">
        <h3>这里是子组件</h3>
        <slot></slot>
    </div>
</template>

注意:一个组件中只能有一个默认插槽。

具名插槽

父组件:

<template>
  <div class="container">
    <h3>这里是父组件</h3>
    <child>
      <div class="one" slot="one">
        <span>菜单1</span>
      </div>
      <div class="two" slot="two">
        <span>菜单-1</span>
      </div>
      <div class="three">
        <span>菜单->1</span>
      </div>
    </child>
  </div>
</template>

子组件:

<template>
  <div class="child">
    // 具名插槽
    <slot name="one"></slot>
    <h3>这里是子组件</h3>
    // 具名插槽
    <slot name="two"></slot>
    // 匿名插槽
    <slot></slot>
  </div>
</template>

注意:一个组件中可以有多个具名插槽,因为有name属性可以进行区分。

作用域插槽

所谓的作用域插槽,就是携带数据的插槽,在父组件里使用携带的数据,并进行数据的展示,换句话说父组件控制样式,子组件控制展示的内容。
父组件:

//test.vue
<div>
   <slot :usertext="user">{{user.lastName}}</slot>
</div>

// 定义内容
data() {
   return {
      user: {
        firstName: "Fan",
        lastName: "Jun"
      }
   }
}

// home.vue
<div>
  <test v-slot:default="slotProps">
    {{slotProps.usertext.firstName}}
  </test>
</div>

v-slot

在vue2.6中,上述的API被软废弃,取而代之的是内置指令v-slot,可以缩写为#

具名插槽

子组件:

<template>
  <div class="child">
    // 具名插槽
    <slot name="one"></slot>
    <h3>这里是子组件</h3>
    // 具名插槽
    <slot name="two"></slot>
    // 匿名插槽
    <slot></slot>
  </div>
</template>
<base-layout>
  <template v-slot:one>
    <h1>Here might be a page title</h1>
  </template>
  <p>A paragraph for the main content.</p> 
  <p>And another one.</p>
  <template v-slot:two>
    <p>Here's some contact info</p>
  </template>
</base-layout>

请注意,v-slot只能添加到template或自定义组件上,这点与弃用的slot属性不同

作用域插槽

有时候,我们想在父组件中访问子组件内部的一些可用数据。例如,假设有一个下面模板的 <current-user> 组件:
子组件:

<template>
  <div>
    <slot :user="user">
      {{user.lastName}}
    </slot>
  </div>
</template>

父组件:

<template>
  <div id="app">
    <user-info v-slot="slotProps">
      {{slotProps.user.lastName}}
    </user-info>
  </div>
</template>

// 插槽内容可以解构,如下
<template>
  <div id="app">
    <user-info v-slot="{user}">
      {{user.lastName}}
    </user-info>
  </div>
</template>

具名插槽+作用域插槽

子组件:

<template>
  <div>
    <slot name="one" :user="user">
      {{user.lastName}}
    </slot>
  </div>
</template>

父组件:

<template>
  <div id="app">
    <user-info>
      <template v-slot:one="userInfo">
        {{userInfo.user}}
      </template>
    </user-info>
  </div>
</template>

命名插槽简写

2.6.0+新增

使用#代替v-slot,如下

// 作用域插槽
<template>
  <div id="app">
    <user-info #default="{user}">
      {{user.lastName}}
    </user-info>
  </div>
</template>

// 具名插槽
<base-layout>
  <template #one>
    <h1>Here might be a page title</h1>
  </template>
  <p>A paragraph for the main content.</p> 
  <p>And another one.</p>
  <template #two>
    <p>Here's some contact info</p>
  </template>
</base-layout>