Vue 之组件插槽Slot用法(组件间通信一种方式)

1)插槽由来和分类

在某些场景中,我们可能想要在父组件为子组件传递一些模板片段,让子组件在它们的组件中渲染这些片段。

这就是插槽的作用。插槽分多种,默认插槽、具名插槽、条件插槽、动态插槽、作用域插槽。

2)插槽类型和举栗子

1.默认插槽

复制代码
<slot></slot>

举栗子:

父组件:子组件的插槽写在哪里,父组件传递的内容就在哪里展示

复制代码
<template>
  <div>我是父组件</div>
  <son>
    我是父组件给子组件的插槽
  </son>
</template>

<script setup>
import son from './son.vue'
</script>

子组件:

复制代码
<template>
  <h3>我是子组件</h3>
  <br>
  <slot></slot>
</template>

2.具名插槽,一个子组件可以存在多个

复制代码
<slot name="header"></slot>
<slot name="footer"></slot>

父组件:父组件使用具名插槽有2种写法

复制代码
<template>
  <div>我是父组件</div>
  <son>
    我是父组件给子组件的插槽
    <!-- 具名插槽写法1 -->
    <!-- <template v-slot:header>
      header插槽
    </template> -->
    <!-- 具名插槽写法2 -->
    <template #header>
      header插槽
    </template>
  </son>
</template>

子组件:

复制代码
<template>
  <h3>我是子组件</h3>
  <br>
  <slot></slot>
  <br>
  <slot name="header"></slot>
</template>

3.条件插槽,主要是为了给插槽提供额外的样式

复制代码
  <div v-if="slots.header" class="trans-header">
    <slot name="header"></slot>
  </div>
  <div v-if="slots.footer" class="trans-footer">
    <slot name="footer"></slot>
  </div>

举栗子:

父组件:

复制代码
<template>
  <div>我是父组件</div>
  <son>
    <template #header>
      header插槽
    </template>
    <template #footer>
      footer插槽
    </template>
  </son>
</template>

<script setup>
import son from './son.vue'
</script>

子组件:

复制代码
<template>
  <h3>我是子组件</h3>
  <br>
  <slot></slot>
  <br>
  <div v-if="slots.header" class="trans-header">
    <slot name="header"></slot>
  </div>
  <div v-if="slots.footer" class="trans-footer">
    <slot name="footer"></slot>
  </div>
</template>

<script setup>
import { onMounted, useSlots } from "vue";
const slots = useSlots()
onMounted(() => {
  // 可以通过slots判断传递了哪些插槽
  console.log(slots);
})

</script>

4.动态插槽,动态传入插槽名

复制代码
<son>
  <!-- 该属性dynamicSlotName为动态数据,在js定义并传递 -->
  <template v-slot:[dynamicSlotName]>
    ...
  </template>

  <!-- 缩写为 -->
  <template #[dynamicSlotName]>
    ...
  </template>
</son>

5.作用域插槽

父组件:父组件传递给子组件的数据,可以通过插槽再次传递给父组件使用,封装组件时非常常用

复制代码
<template>
  <div>我是父组件</div>
  <son :obj1="obj1" :obj2="obj2">
    我是父组件给子组件的插槽
    <template #header="slot">
      header插槽{{ slot.obj1 }}
    </template>
    <template #footer="slot">
      footer插槽{{ slot.obj2 }}
    </template>
  </son>
</template>

<script setup>
import { reactive } from 'vue';
import son from './son.vue'
const obj1 = reactive({ name: '羊羊', age: 12 });
const obj2 = reactive({ name: '猫猫', age: 2 });
</script>

子组件:

复制代码
<template>
  <h3>我是子组件</h3>
  <br>
  <slot></slot>
  <br>
  <slot name="header" :obj1="obj1"></slot>
  <slot name="footer" :obj2="obj2"></slot>
</template>

<script setup>
const props = defineProps({
  obj1: {
    type: Object, default: () => { }
  },
  obj2: {
    type: Object, default: () => { }
  },
})
</script>

如有不足,欢迎指正。

不要忽视你达成的每个小练习,它是你前进路上的垫脚石。冲!

相关推荐
二哈喇子!9 分钟前
Vue 组件化开发
前端·javascript·vue.js
chxii32 分钟前
2.9 插槽
前端·javascript·vue.js
姑苏洛言1 小时前
扫码点餐小程序产品需求分析与功能梳理
前端·javascript·后端
Freedom风间1 小时前
前端必学-完美组件封装原则
前端·javascript·设计模式
江城开朗的豌豆1 小时前
React表单控制秘籍:受控组件这样玩就对了!
前端·javascript·react.js
一枚前端小能手2 小时前
📋 代码片段管理大师 - 5个让你的代码复用率翻倍的管理技巧
前端·javascript
国家不保护废物2 小时前
Web Worker 多线程魔法:告别卡顿,轻松实现图片压缩!😎
前端·javascript·面试
接着奏乐接着舞。2 小时前
如何在Vue中使用拓扑图功能
前端·javascript·vue.js
老华带你飞2 小时前
生产管理ERP系统|物联及生产管理ERP系统|基于SprinBoot+vue的制造装备物联及生产管理ERP系统设计与实现(源码+数据库+文档)
java·数据库·vue.js·论文·制造·毕设·生产管理erp系统
阳先森2 小时前
Vue3 Proxy 为何不直接返回target[key],选用Reflect
前端·vue.js