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>

posted @ 2024-04-16 18:12  songxia777  阅读(9)  评论(0编辑  收藏  举报