vue插槽

397 阅读2分钟

对vue插槽的内容回顾和记录总结。参照vue 2.6.0及之后的版本。

在 2.6.0 中,我们为具名插槽和作用域插槽引入了一个新的统一的语法 (即 v-slot 指令)。它取代了 slot 和 slot-scope 这两个目前已被废弃但未被移除且仍在文档中的 attribute。新语法的由来可查阅这份 RFC。

用途

插槽主要是用在组件中可灵活变动的地方,不过,最近遇到gs代码规范不让使用v-html,那也可以用插槽达到同样效果。

基础使用

<base-dialog>
    <template v-slot:header>
        <div class="parent-header-class">
            <span>{{title}}</span>
            <span class="icon"></span>
        </div>
    </template>
</base-dialog>

// BaseDialog.vue

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

后备内容

<base-dialog>
    <template v-slot:header>
        <div class="parent-header-class">
            <span>{{title}}</span>
        </div>
    </template>
</base-dialog>

// BaseDialog.vue

<template>
    <div>
        <slot name="header">默认标题</slot>
    </div>
<template>

具名插槽

name属性定义插槽名称,多个插槽时便于区分。

<base-dialog>
    <template v-slot:header>
        <p>header slot content</p>
    </template>
    
    <p>default slot content</p>
    
</base-dialog>

// BaseDialog.vue

<template>
    <div>
        <slot name="header">默认标题</slot>
        <slot>默认default插槽内容</slot>
    </div>
<template>

同样vue也提供了$slots获取传入的所有插槽。

具名插槽缩写

v-slot:header简写为#header

<base-dialog>
    <template #header>
        <p>header slot content</p>
    </template>
    
    <p>default slot content</p>
    
</base-dialog>

// BaseDialog.vue

<template>
    <div>
        <slot name="header">默认标题</slot>
        <slot>默认default插槽内容</slot>
    </div>
<template>

注意默认插槽有参数时不能简写为#="slotProps"必须写插槽的名称#default="slotProps"

作用域插槽

插槽内的内容的作用域是父元素的作用域,那如果插槽需要访问组件内的数据呢,可以通过v-bind绑定到插槽传入。

<base-dialog>
    <template v-slot:header="slotProps">
        <p>{{slotProps.userName}}</p>
    </template>
    
    <p>default slot content</p>
    
</base-dialog>

// BaseDialog.vue

<template>
    <div>
        <slot name="header" :userName="userName">默认标题</slot>
        <slot>默认default插槽内容</slot>
    </div>
<template>
...
data () {
    return {
        userName: 'xxx'
    }
}

解构插槽prop

<base-dialog>
    <template v-slot:header="{ userName }">
        <p>{{userName}}</p>
    </template>
    
    <p>default slot content</p>
    
</base-dialog>

// BaseDialog.vue

<template>
    <div>
        <slot name="header" :userName="userName">默认标题</slot>
        <slot>默认default插槽内容</slot>
    </div>
<template>
...
data () {
    return {
        userName: 'xxx'
    }
}

独占默认插槽prop

只有一个默认插槽的时候使用,多个插槽的时候不可以,因为会混淆。

<base-dialog v-slot="{ userName }">
    <p>{{ userName }}</p>
</base-dialog>

// BaseDialog.vue

<template>
    <div>
        <slot :userName="userName">默认default插槽内容</slot>
    </div>
<template>
...
data () {
    return {
        userName: 'xxx'
    }
}

注意默认插槽的缩写语法不能和具名插槽混用,因为它会导致作用域不明确.

动态插槽名

<base-dialog>
    <template v-slot:[slotName]>
        <p>{{ userName }}</p>
    </template>
</base-dialog>

参考

vue 插槽