vue 插槽的使用和插槽的本质

插槽的作用

Vue 插槽是组件化开发中非常重要的功能,它主要有以下几个核心作用:

内容分发:允许父组件向子组件注入内容,实现组件的内容定制;

数据通讯:子组件可以向插槽传递数据,实现数据与展示分离,父组件决定如何渲染子组件提供的数据;

增强组件复用性:同一组件可以适应多种使用场景,通过不同插槽内容实现不同视觉效果;

插槽机制是Vue组件化设计中最重要的特性之一,可以大大提高组件的可复用性和灵活性。

插槽的基本使用

代码中用到了三种类型的插槽 默认插槽、具名插槽、作用域插槽。

子组件

vue 复制代码
<template>
  <div class="slotComp">
    <slot></slot>
    <slot name="slotB"></slot>
    <slot name="slotC" :msg="message"></slot>
  </div>
</template>
<script lang="ts" setup>
let message = ref('作用域插槽')
</script>
<style lang="scss" scoped>
.slotComp {
  height: 100%;
}
</style>

父组件

vue 复制代码
<template>
  <div class="vSlot-container">
    <slot-comp>
      <p>默认插槽</p>
      <template #slotB>
        <p>具名插槽</p>
      </template>
      <template #slotC="slotProps">
        <p>{{ slotProps.msg }}</p>
      </template>
    </slot-comp>
  </div>
</template>
<script setup lang="ts">
import SlotComp from '@/views/directive/components/slotComp.vue'
</script>
<style scoped lang="scss">
.vSlot-container {
  height: 100%;
}
</style>

上面是插槽的基本用法

插槽的本质

插槽的本质就是函数 下面举个例子,用另一种方式实现默认插槽、具名插槽和作用域插槽

子组件

现在子组件是第一个TS文件 setup函数接收两个参数:

props:接收父组件传递的 props 值;

context:包含四个组件属性 attrs(接收非 props 的属性)、slots(接收插槽内容)、emit(用于触发事件)、expose(显式暴露组件公共实例内容);

createElementVNode() 用于创建虚拟节点 接收以下三个参数:

type:节点类型

props:属性/Props(可选)

children:子节点

这里只用到 slots 属性,所以只介绍slots属性,通过下面的打印可以看出,slots 的本质是个对象 ,对象里面包含了调用插槽的函数

ts 复制代码
import { createElementVNode } from 'vue'
export default {
  setup(props, ctx) {
    console.log(props, ctx)
    return () => createElementVNode('div', null, [])
  },
}

结合上面插槽的基本使用,不难发现,使用插槽是父组件给子组件传递了一个对象,对象里面包含了 插槽的函数,在子组件中调用函数,将函数的返回结果渲染到页面

下面调用函数实现插槽功能

ts 复制代码
import { createElementVNode } from 'vue'
export default {
  setup(props, { slots }) {
    const defaultSlot = slots.default()
    const slotB = slots.slotB()
    const slotC = slots.slotC({ msg: '作用域插槽' })
    console.log('slotC', slotC)
    return () =>
      createElementVNode('div', null, [...defaultSlot, ...slotB, ...slotC])
  },
}

下面的效果跟单文件组件的效果一样,并且可以看到插槽函数执行之后返回的虚拟节点,这些虚拟节点就是要渲染到页面上的

总结

插槽的本质是个函数,在父组件传递给子组件一个包含插槽内容的对象(称为 slots),子组件模板中的 标签会被替换为对 slots 对象的调用;父组件先渲染自己的内容,但不立即渲染插槽内容,将插槽内容保存为函数(作用域插槽是带参数的函数),子组件渲染时调用这些函数获取实际的 VNode。

相关推荐
浩星8 分钟前
iframe引入界面有el-date-picker日期框,点击出现闪退问题处理
前端·vue.js·elementui
技术钱10 分钟前
element plus 多个form校验
前端
yume_sibai19 分钟前
HTML HTML基础(3)
前端·html
米花丶27 分钟前
JSBridge安全通信:iOS/Android桥对象差异与最佳实践
前端·webview
萌萌哒草头将军1 小时前
🚀🚀🚀 Oxc 恶意扩展警告;Rolldown 放弃 CJS 支持;Vite 发布两个漏洞补丁版本;Rslib v0.13 支持 ts-go
前端·javascript·vue.js
接着奏乐接着舞。1 小时前
3D地球可视化教程 - 第1篇:基础地球渲染系统
前端·javascript·vue.js·3d·three.js
龙傲天6661 小时前
Scala的面向对象和函数式编程特性 Idea环境搭建和输入输出
前端
蓝色海岛1 小时前
element-ui表格嵌套表格,鼠标移入时样式错乱-问题调研及处理办法
前端
薄雾晚晴1 小时前
Rspack 实战:用 SWC Loader 搞定 JS 兼容(支持 IE 11 + 现代浏览器,兼顾构建速度)
前端·vue.js
恋猫de小郭2 小时前
Flutter 官方 LLM 动态 UI 库 flutter_genui 发布,让 App UI 自己生成 UI
android·前端·flutter