Vue 组件插槽

默认插槽的定义与使用

<!-- 组件 test 定义 -->
<template>
    <button>
        <slot>提交</slot>
    </button>
</template>


<!-- 父组件调用 -->
<template>
    <test>保存</test>
</template>

 

具名插槽的定义与使用

<!-- 组件 test 定义 -->
<template>
    <div class="header-container">
        <slot name="header"></slot>
    </div>
    
    <div class="body-container">
        <slot name="body"></slot>
    </div>
    
    <div class="footer-container">
        <slot name="footer"></slot>
    </div>
</template>


<!-- 父组件调用 -->
<template>
    <test>
        <template #header>
            <div class="bg-primary text-white">这是头部</div>
        </template>
        
        <template #body>
            <div class="bg-light text-danger">这是主体部份</div>
        </template>
        
        <template #footer>
            <div class="bg-info text-primary">这是底部</div>
        </template>
    </test>
</template>

 

 

动态插槽名的定义

<template v-slot:[dynamicSlotName]>...</template>

 

 

插槽内容访问数据说明:

一、默认下插槽内容无法访问子组件的数据。其只能访问当前父组件数据。

二、但是我们可以通过以下方式,使插槽内容能够访问子组件的数据:

<!-- 组件 test 定义 -->
<template>
    <div class="header-container">
        <!-- 在slot 上,绑定数据属性 -->
<!-- 注意: name 属性是系统属性,它不会传递给插槽内容 -->
<slot name="header" :title="data.title" :date="data.date"></slot> </div> <div class="body-container"> <slot name="body" :text="data.text"></slot> </div> <div class="footer-container"> <slot name="footer" :copyright="data.copyright"></slot> </div> </template> <script setup> import { ref } from 'vue' const data = ref({ title: '文章标题', date: '发表时间', text: '文章正文', copyright: '版权声明' }) </script> <!-- 父组件调用 test --> <template> <test> <!-- 在这里指定 slot的name 对应的插槽必需对应的name属性值,比如这里将header改成body是错误的 --> <template #header="header"> <!-- 这里是 slot.属性 的取值方式 --> <div class="bg-primary text-white">{{header.title}}</div> </template> <template #body="body"> <div class="bg-light text-danger">{{body.text}}</div> </template> <template #footer="footer"> <div class="bg-info text-primary">{{footer.copyright}}===这是底部</div> </template> </test> </template>

 注意:父组件在插槽内容中,无法修子组件数据。它是只读的,比如:

<template>
    <test>
        <template #header="header">
            <input  type="text" placeholder="输入新标题" @input="header.title = $event.detail.value"/> <!-- 无法修改 -->
        </template>
    </test>
</template>

 

扩展知识:

useSlot() 函数

可以用来判断父组件是否调用了指定的slot。注意,这个函数使用在子组件内。

子组件代码:

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

<script lang="ts" setup>
import { useSlots } from "vue";
//值为true表示父组件中含有 default 插槽内容
const slotDefault = !!useSlots().default;
//值为true表示父组件中含有 test 插槽内容 const slotTest = !!useSlots().test; </script>

 

posted @ 2022-09-19 08:27  1024记忆  阅读(303)  评论(0编辑  收藏  举报