Vue插槽

150 阅读1分钟
  • Vue实现了一套内容分发的API,将slot元素作为承载分发内容的出口
  • 插槽可以包含任何模板代码,包括html,甚至其他组件也可以
  • 父级模板里的所有内容都是在父级作用域中编译的,子模板里的所有内容都是在子作用域中编译的

1.默认插槽(后备内容)

  • 当插槽中没有提供值时,会显示默认内容 默认xxx 当没有传入值时即会显示 默认xxx
// html部分
<default-slot>显示这句话,不显示默认插槽内容</default-slot>
<default-slot></default-slot>
// js部分
Vue.component('default-slot', {
    data: function () {
        return {
            title: '我是默认插槽组件'
        }
    },
    template: `
            <div>
                <h2>{{title}}</h2>
                <slot>默认插槽,当没有传入值时就显示当前语句</slot>
            </div>
        `
});

2.具名插槽

  • 有时我们需要多个插槽,元素有一个特殊的 attribute: name
  • 在向具名插槽提供内容的时候,我们可以在一个template元素上使用v-slot指令,并以v-slot的参数的形式提供其名称
// html部分
<name-slot>
    <template name="slot1">
        具名插槽slot1的内容
    </template>
    <template name="slot2">
        具名插槽slot2的内容
    </template>
</name-slot>
// js部分
Vue.component('name-slot', {
        data: function () {
            return {
                title: '我是具名插槽组件'
            }
        },
        template: `
                <div>
                    <h2>{{title}}</h2>
                    <slot name="slot1"></slot>
                    <slot name="slot2"></slot>
                </div>
            `
    })

3.作用域插槽

  • 为了让插槽内容能够访问子组件中才有数据
  • 子组件用v-bind传给出去, 父组件用v-slot接收

3.1如果子组件只v-bind一个值, 父组件就用v-slot: default

// html部分
<child-one-data v-slot:default="title">
    {{title}}
</child-one-data>
// js部分
Vue.component("child-one-data", {
    data: function () {
        return {
            title: '只有一个值'
        }
    },
    template: `
        <div>
            <slot v-bind:title="title"></slot>
        </div>
    `
});

3.2如果子组件传递多个值

<!-- 子组件传递多个值 -->
<template v-slot:title1="titleData1">
    <p>{{titleData1}}</p>
</template>
<template v-slot:title2="titleData2">
    <p>{{titleData2}}</p>
</template>
// 如果子组件传递多个值
Vue.component("child", {
    data: function () {
        return {
            list: [{
                name: '玫瑰一束'
            }, {
                name: '零食一包'
            }],
            title1: '标题1',
            title2: '标题2'
        }
    },
    template: `
        <div>
            <slot v-bind:childList="list" name="child1"></slot>
            <slot v-bind:titleData1="title1" name="title1"></slot>
            <slot v-bind:titleData2="title2" name="title2"></slot>
        </div>
    `
})

3.3解构插槽prop

<template v-slot="{childList}">
    <ul>
        <li v-for="item in childList">解构名称:{{item.name}}</li>
    </ul>
</template>
<!-- 作用域插槽,只有当解构插槽prop的时候 v-slot也可以用#代替 -->
<template #child1="{childList}">
    <ul>
        <li v-for="item in childList">解构名称:{{item.name}}</li>
    </ul>
</template>