vue中的slot——作用域插槽

作用域插槽的作用是可以访问子组件的数据,相当于父组件可以直接在slot范围内使用子组件的数据。如果对插槽的基本知识不熟悉,可以参考vue中的slot——单个插槽和具名插槽

一、作用域插槽中单个组件的写法

作用域插槽允许我们将插槽转换为可复用的模板,这些模板可以基于子组件传来的数据渲染出不同的内容。这在设计封装数据逻辑同时允许父级组件自定义部分布局的可复用组件时是最有用的。
举个使用的例子。在子组件中,里有一个type类型数据。在父组件中,我们想要获取子组件的type数据,并在父组件的插槽里根据不同的type显示不同的内容,代码如下:

子组件
<template>
    <div>
        <slot v-bind:type="type"></slot>
    </div>
</template>

<script lang="ts">
    import { Vue, Component } from 'vue-property-decorator';
    @Component({})
    export default class Dialog extends Vue {
        type = 1;
    }
</script>

为了让type在父级的插槽内容中可用,需要将type作为<slot>元素的一个属性绑定上去,绑定在<slot>元素上的属性被称为插槽prop,这就相当于子组件将type数据传递给父组件了。

父组件
<template>
    <SlotComponent>
        <template v-slot:default="slotProps">
            <div v-if="slotProps.type === 1">
                我是类型1
            </div>
            <div v-else-if="slotProps.type === 2">
                我是类型2
            </div>
        </template>
    </SlotComponent>
</template>

在父组件中如何获取到子组件传递来的type呢?需要使用v-slot来定义子组件传递过来的数据集合的名字,例子中名字使用的是slotProps,当然也可以使用任何你喜欢的名字。如果要获取子组件传过来的type的话,可以通过slotProps.type获取。这里可以优化下,用解构的话写起来会更方便。

<template v-slot:default="{type}">
    <div v-if="type === 1">
        我是类型1
    </div>
    <div v-else-if="type === 2">
        我是类型2
    </div>
</template>

v-slot后面跟着的:default是什么?这里的:default表示的是单个插槽,也可以省略,直接写成v-slot="slotProps"不过这个缩写语法只限于单个插槽的情况,如果是具名插槽的话会报错

二、作用域插槽中具名组件的写法

下面是具名插槽的写法,可以作为了解一下。如果是具名插槽的话子组件会分别给每个slot绑定数据。在父组件中每个v-slot:后面需要加上对应插槽的名字,这样就可以在对应slot下面使用子组件的数据了。

子组件
<template>
    <div>
        <slot name="header" v-bind:headerData="headerData"></slot>
        <slot name="footer" v-bind:footerData="footerData"></slot>
    </div>
</template>

<script lang="ts">
    import { Vue, Component } from 'vue-property-decorator';
    @Component({})
    export default class Dialog extends Vue {
        headerData = '我是头部数据';
        footerData = '我是底部数据';
    }
</script>
父组件
<template>
    <SlotComponent>
        <template v-slot:header="{headerData}">
            {{headerData}}
        </template>
        <template v-slot:footer="{footerData}">
            {{footerData}}
        </template>
    </SlotComponent>
</template>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容