06 Vue3插槽
默认插槽、具名插槽 一般是用于 父传子
作用域插槽 一般是用于 子传父
默认插槽
父组件
<template>
<h2>父组件</h2>
<!-- 显示 title smailltitle 和 自定义内容 -->
<Child title="今日头条" smailltitle="新闻最前沿"> 自定义 今日头条 数据 </Child>
<!-- 显示 title 和 自定义内容 -->
<Child title="昨日新闻"> 自定义 昨日新闻 数据 </Child>
<!-- 显示 title ,因为没有自定义内容,所以显示默认插槽的默认内容 -->
<Child title="娱乐新闻" />
</template>
<script lang="ts" setup>
import Child from '@/components/Child.vue';
</script>
<style scoped lang="scss"></style>
子组件
<template>
<hr />
<h2>子组件</h2>
{{ title }}=={{ smailltitle }}
<br />
<!--
设置一个默认插槽[slot],默认插槽的名称是default
默认内容【可选值】:如果父组件没有数据显示,就显示默认内容;
如果父组件有自己的数据显示,就显示父组件自定义的数据-->
<slot>默认内容</slot>
</template>
<script lang="ts" setup>
import { defineProps } from 'vue';
defineProps<{
title: string; // 接收 string 类型的 title
smailltitle?: string; // 接收 string 类型的 smailltitle 【可选值】
}>();
</script>
具名插槽
父组件
<template>
<h2>父组件</h2>
<!-- 显示 title smailltitle 和 自定义内容 -->
<Child title="今日头条" smailltitle="新闻最前沿">
<!-- 插槽的命名一般是用于 【template】 标签 和 组件 标签中 -->
<template #s1> 自定义 今日头条 数据1 </template>
<template v-slot:s2> 自定义 今日头条 数据2 </template>
</Child>
</template>
<script lang="ts" setup>
import Child from '@/components/Child.vue';
</script>
<style scoped lang="scss"></style>
子组件
<template>
<hr />
<h2>子组件</h2>
{{ title }}=={{ smailltitle }}
<br />
<!--
具名插槽:设置插槽的名称,用来插槽指定的位置(占坑)
-->
<slot name="s1">默认内容</slot>
<slot name="s2">默认内容</slot>
</template>
<script lang="ts" setup>
import { defineProps } from 'vue';
defineProps<{
title: string; // 接收 string 类型的 title
smailltitle?: string; // 接收 string 类型的 smailltitle 【可选值】
}>();
</script>
作用域插槽
数据在组件的自身(子组件中),但根据数据生成的结构需要组件的使用者(父组件)来决定
父组件一般是接收来自子组件的数据
父组件
<template>
<h2>父组件</h2>
<!-- 默认default的作用域插槽 -->
<Child #default="params">
<ul>
<li v-for="g in params.games" :key="g.id">{{ g.name }}</li>
</ul>
</Child>
<!-- 具名作用域插槽:v-slot:abc="params" 或者 #abc="params" -->
<Child #abc="params">
<ul>
<li v-for="g in params.games" :key="g.id">{{ g.name }}</li>
</ul>
</Child>
<!-- 具名作用域插槽:结构参数 -->
<Child #abc="{ games }">
<ul>
<li v-for="g in games" :key="g.id">{{ g.name }}</li>
</ul>
</Child>
</template>
<script lang="ts" setup>
import Child from '@/components/Child.vue';
</script>
<style scoped lang="scss"></style>
子组件:定义数据
<template>
<hr />
<h2>子组件</h2>
<h3>今日榜单游戏</h3>
<br />
<!--
作用域插槽:在组件自身(子组件中)定义数据,而数据的结构由使用这决定
-->
<!-- 默认default的作用域插槽 -->
<slot :games="games"></slot>
<!-- name为abc的作用域插槽 -->
<slot name="abc" :games="games"></slot>
</template>
<script lang="ts" setup>
import { reactive } from 'vue';
let games = reactive([
{ id: 'asgdytsa01', name: '英雄联盟' },
{ id: 'asgdytsa02', name: '王者荣耀' },
{ id: 'asgdytsa03', name: '红色警戒' },
{ id: 'asgdytsa04', name: '斗罗大陆' },
]);
</script>