Vue3
中slot插槽的使用
插槽在什么时候使用呢?
在vue
中 我们要使用子组件的时候需要给子组件传一些特定的模板,这个时候你就需要用插槽。 插槽在一些封装组件中有很大的用处,插槽有匿名插槽、后备内容、具名插槽、作用域插槽,下面我们就通过一些例子来学习一下
插槽的基本使用
1 定义一个子组件child.vue
<template>
<div class="child-con">
<p>我是子组件2</p>
<slot></slot> <!--插槽的出口 -->
</div>
</template>
<script setup lang="ts">
</script>
<style scoped>
</style>
2.定义一个父组件,然后父组件引入子组件
<template>
<div class="test-con">
<p>我是父组件1</p>
<child></child>
</div>
</template>
<script setup lang="ts">
import Child from "./components/child.vue";
</script>
<style scoped>
</style>
此时页面变成了
我们可能想要为子组件传递一些特别模板片段
<template>
<div class="test-con">
<p>我是父组件1</p>
<child>
<div>向子组件传递一些特别模板片段</div>
</child>
</div>
</template>
<script setup lang="ts">
import Child from "./components/child.vue";
</script>
此时页面变成了
我们发现在标签之间插入的内容被渲染出来了,前面我们说 slot 就是挖了一个槽出来,可以放置东西
,这里我们在父组件中添加的 div 便就是我们要添加的东西,子组件中 slot 标签被替换为了我们插入的 div 元素。这就是插槽的最基本使用。
定义组件插槽设置默认内容
1.修改一下 child.vue
代码:
<template>
<div class="child-con">
<p>我是子组件2</p>
<slot>
<p>我是默认内容</p>
</slot> <!--插槽的出口 -->
</div>
</template>
此时页面
2.那么我们我们往 child 组件传入一点内容会是什么效果呢?
<template>
<div class="test-con">
<p>我是父组件1</p>
<child>
<div>{{ message }}</div>
</child>
</div>
</template>
<script setup lang="ts">
import Child from "./components/child.vue";
import { ref } from "vue";
const message = ref("这是父组件向子组件插入的message");
</script>
此时页面变成了
有上面的例子看出slot 标签内的内容就是默认内容,也就是当父组件没有传递给子组件内容时,子组件就会默认渲染 slot 内部的内容,但是当父组件有传递给子组件内容时,就会显示父组件传的内容
具名插槽
很多时候子组件都不止一个slot,我们可能允许调用者同时传入多个slot,这个时候为了区分插槽与内容的对应关系,我们可以分别给 slot 和内容都加上一个名字,插入插槽的时候大家按照名字区分好就可以了,这就是具名插槽
1.基本使用
给子组件child.vue
添加3个slot 两个有name
,一个没有name
<template>
<div class="child-con">
<p>我是子组件2</p>
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
</template>
父组件 根据name添加内容, 简写:v-slot:header可以简写成#header
<template>
<div class="test-con">
<p>我是父组件1</p>
<child>
<template v-slot:header>
<div>我是 header:{{ message }}</div>
</template>
<div>我没有name:{{ message }}</div>
<template v-slot:footer>
<div>我是 footer:{{ message }}</div>
</template>
</child>
</div>
</template>
<script setup lang="ts">
import Child from "./components/child.vue";
import { ref } from "vue";
const message = ref("这是父组件向子组件插入的message");
</script>
此时页面
由上面页面可以看出,我们传入的内容都渲染到了对应的插槽内,没有命名的插槽渲染了我们传入的未添加指令的内容。
2.动态插槽名
前面我们给插槽命名的时候都是直接写死的,其实我们有时候可以动态给插槽命名的,以满足更多的业务场景slotName
可以动态传
<template v-slot:[slotName]>
插槽作用域问题
面父组件代码中 message 是我们在父组件中定义的数据,但是在我们的子组件 child 中渲染了出来,说明子组件中的插槽是可以访问到父组件中的数据作用域的,但是反过来是不行的,因为我们无法通过插槽拿到子组件的数据。但是,万一我们有需求就是需要在插槽内容中获取子组件数据怎么办呢?
子组件child.vue
<template>
<div class="child-con">
<p>我是子组件2</p>
<header>
<slot text="我是子组件的text" :count="1" name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
</template>
父组件 v-slot:header=""
接收 也可以简写成#header=""
<template>
<div class="test-con">
<p>我是父组件1</p>
<child>
<template v-slot:header="{ text, count }">
<div>{{ text }}---我是子组件的count:{{ count }}</div>
<div>我是 header:{{ message }}</div>
</template>
<div>我没有name:{{ message }}</div>
<template v-slot:footer>
<div>我是 footer:{{ message }}</div>
</template>
</child>
</div>
</template>
此时页面
水平有限有问题欢迎在评论区指出,一起讨论探索,如果对您有帮助,请点赞和收藏哦 感谢!!!