Vue 基础组件二次封装的高级技巧及方法,能更优雅的进行二次封装组件(props 属性和 event 事件的透传、子组件插槽暴露、第三方组件方法继承)

news2024/11/16 15:41:11

前言

本人持续开源了Vue2基于ElementUi&AntdUi再次封装的Tui基础组件和Vue3基于Element-plus再次封装的TuiPlus基础组件,在组件封装的过程中提取了 props 属性和 event 事件的透传、子组件插槽暴露等,借此总结一下!!大佬略过!

接下来我以Vue2基于ElementUi再次封装的基础组件(Tui)为例进行讲解:

一、如何继承第三方组件的属性

1、el-select就有二十几个属性(Attributes

在这里插入图片描述

2、我们不应该在组件中一个一个的定义props

3、因此我需要$attrs

$attrs:组件实例的该属性包含了父作用域中不作为 prop 被识别 (且获取) 的 attribute 绑定 (class和style除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (classstyle除外),并且可以通过v-bind="$attrs"传入内部的 UI 库组件中。

<template>
  <div class="t_select">
    <el-select
      v-model="childSelectedValue"
      :style="{width: width||'100%'}"
      v-bind="attrs"
    >
      <el-option
        v-for="(item,index) in optionSource"
        :key="index+'i'"
        :label="item[labelKey]"
        :value="item[valueKey]"
      ></el-option>
    </el-select>
  </div>
</template>
<script>
export default {
  name: 'TSelect',
  computed: {
    attrs() {
      return {
        // 'popper-append-to-body': false,
        clearable: true, // 默认开启清空
        filterable: true, // 默认开启过滤
        ...this.$attrs
      }
    }
  }
</script>

二、如何继承第三方组件的Event 事件

1、el-select就有6个事件

在这里插入图片描述

2、我们不应该在组件中一个一个的$emit

3、因此我需要$listeners

$listeners:组件实例的该属性包含了父作用域中的(不含.native修饰器的)v-on事件监听器。它可以通过v-on="$listeners"转发传入内部组件,进行对事件的监听处理。

<template>
  <div class="t_select">
    <el-select
      v-model="childSelectedValue"
      :style="{width: width||'100%'}"
      v-bind="attrs"
      v-on="$listeners"
    >
      <el-option
        v-for="(item,index) in optionSource"
        :key="index+'i'"
        :label="item[labelKey]"
        :value="item[valueKey]"
      ></el-option>
    </el-select>
  </div>
</template>

三、如何使用第三方组件的Slots

1、el-input就有4个Slot

在这里插入图片描述

2、我们不应该在组件中一个一个的去手动添加<slot name="prefix">

3、因此我需要$slots$scopedSlots

$slots:普通插槽,使用$slots这个变量拿到非作用域的插槽,然后循环渲染对应的普通具名插槽,这样就可以使用第三方组件提供的原插槽;
$scopedSlots:作用域插槽则绕了一圈,使用了一个插槽的语法糖(具名插槽的缩写)并且结合着动态插槽名的用法;循环$scopedSlots作用插槽位置和传递对应的参数,,这样就可以使用第三方组件提供的作用域插槽。

<template>
  <div class="t_input">
    <el-input
      v-model="childSelectedValue"
      v-bind="attrs"
      v-on="$listeners"
    >
     <!-- 遍历子组件非作用域插槽,并对父组件暴露 -->
     <template v-for="(index, name) in $slots" v-slot:[name]>
        <slot :name="name" />
      </template>
      <!-- 遍历子组件作用域插槽,并对父组件暴露 -->
      <template v-for="(index, name) in $scopedSlots" v-slot:[name]="data">
        <slot :name="name" v-bind="data"></slot>
      </template>
    </el-input>
  </div>
</template>

四、如何使用第三方组件的Methods

1、el-table就有个方法

在这里插入图片描述

2、我们不应该在组件中一个一个的去手动添加clearSort() { this.$refs['el-table'].clearSort() }

3、因此我需要在组件中根据this.$refs['el-table']来遍历所有的方法

在这里插入图片描述

mounted() {
    this.extendMethod()
  },
 methods: {
    // 继承el-table的Method
    extendMethod() {
      const refMethod = Object.entries(this.$refs['el-table'])
      for (const [key, value] of refMethod) {
        if (!(key.includes('$') || key.includes('_'))) {
          this[key] = value
        }
      }
    },
   }

五、Vue 3组件封装的变化

1、$attrs$listeners 合并

Vue 3.x 当中,取消了$listeners这个组件实例的属性,将其事件的监听都整合到了$attrs这个属性上了,因此直接通过v-bind=$attrs属性就可以进行 props 属性和 event 事件的透传。

2、$slot$scopedSlots 合并

Vue 3.x当中取消了作用域插槽$scopedSlots的属性,将所有插槽都统一在$slots当中,因此在 Vue 3.x 当中不需要分默认插槽、具名插槽和作用域插槽,可以进行统一的处理。

六、组件源码

基于ElementUi&AntdUi再次封装基础组件文档


vue3+ts基于Element-plus再次封装基础组件文档

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/593854.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

把VS Code打造成后端开发的宇宙IDE,也挺爽

本文首发自「慕课网」&#xff0c;想了解更多IT干货内容&#xff0c;程序员圈内热闻&#xff0c;欢迎关注&#xff01; 作者&#xff1a;维生素P|慕课网优质作者 工欲善其事必先利其器&#xff0c;提高程序员的开发效率必须要有一个好的开发工具。而一旦提到开发工具&#xff…

深度解析Linux读写锁逻辑

一、Linux为何会引入读写锁&#xff1f; 除了mutex&#xff0c;在linux内核中&#xff0c;还有一个经常用到的睡眠锁就是rw semaphore&#xff08;后文简称为rwsem&#xff09;&#xff0c;它到底和mutex有什么不同呢&#xff1f;为何会有rw semaphore&#xff1f;无他&#x…

[Mysql_DB]自动写入系统时间——注意低版本数据库操作

创建商品表包含字段create_time和update_time,并设置默认值为当前时间 实例 使用 CREATE TABLE 语句来创建一个商品表&#xff0c;并为其添加 create_time 和 update_time 字段&#xff0c;同时将这两个字段的默认值设置为当前时间。以下是一个示例&#xff1a; CREATE TABLE …

最新版本 Stable Diffusion 开源 AI 绘画工具之文本转换(Embedding)以及脚本(Script)高级使用篇

✨ 目录 &#x1f388; 文本转换 / Textual Inversion&#x1f388; 自定义Embedding / Textual Inversion&#x1f388; 脚本 / Script&#x1f388; 脚本 / Prompt matrix&#x1f388; 脚本 / X/Y/Z plot &#x1f388; 文本转换 / Textual Inversion 这个功能其实就是将你…

SuperMap Hi-Fi 3D SDK for Unity制作游戏引擎材质

kele 一、使用背景 在交通&#xff0c;电力&#xff0c;规划等行业中&#xff0c;有的对象常常具有很强的质感&#xff0c;比如金属质感的 钢轨&#xff0c;电力塔&#xff1b;陶瓷材质的绝缘子&#xff1b;玻璃材质的建筑幕墙等&#xff0c;但常规方式的表现效果 往往差强人意…

AUTOSAR APP临摹1~Quick Start 模块

已实现逻辑 demo5 页面跳转 mainwindow.ui相当于simulink界面点击Quick Start进入welcome.ui界面在welcome.ui中大概包含7个页面页面之间通过next、back按钮翻页第0页没有back、最后一页点击next退出welcome.ui&#xff0c;回到mainwindow.ui 条件显示 C/C选项页面中&#xff…

7 步提升私有化部署的极狐GitLab 实例安全等级

目录 指导准则 分层安全&#xff0c;纵深防御 保密 ≠ 安全 减少攻击面 7 步保障私有化部署实例安全 第一步&#xff1a;开启多因素认证 第二步&#xff1a;加强额外的注册检查 第三步&#xff1a;限制群组和项目可见性 第四步&#xff1a;强化 SSH 设置 第五步&…

labelimg闪退解决方法(之前使用过labelimg,但新一次使用,打开文件夹无反应,再次打开闪退的问题)

问题描述&#xff1a; 之前使用过labelimg进行好多次的标注&#xff0c;但新一次运行使用&#xff0c;发现打开目录无反应&#xff0c;再次打开闪退的问题&#xff0c;重启电脑并且从新运行labelimg仍然无效。 解决方法&#xff1a; 关闭labelimg&#xff0c;然后删除文件C…

RK平台使用i2c-tools调试

简介 i2ctool是嵌入式开发过程中调试i2c设备常用的工具包&#xff0c;其中比较常用的有&#xff1a;i2cdetect、i2cdump、i2cset、i2cget。 RK平台的SDK大部分默认都会带这个工具&#xff0c;如果没有编译进去或者找不到的情况下可以自己从网上下载编译进去&#xff1a;https:…

数据结构与算法08:二分查找和哈希算法

目录 【二分查找】 二分查找的特殊情况 【哈希算法】 应用一&#xff1a;安全加密 应用二&#xff1a;唯一标识 应用三&#xff1a;数据校验 应用四&#xff1a;散列函数 应用五&#xff1a;负载均衡 应用六&#xff1a;数据分片 应用七&#xff1a;分布式存储&…

vscode:快捷输入代码片段

背景 每次调试代码输入 console.log() 的时候都会想&#xff0c;有没有什么指令我按下了就能生成这行代码&#xff0c;甚至更多我想自定义的代码&#xff0c;然后就去搜了搜果然有&#xff0c;vscode 提供了自定义代码片段的功能。 步骤 打开 vscode&#xff0c;点击 Prefer…

idea连接HiveServer2

一、 启动hive 启动hive的元数据服务 [aahadoop102 hive]$ bin/hive --service metastore根据你hive的配置方式启动hiveserver2 [aahadoop102 hive]$ bin/hive --service hiveserver2二、配置idea连接Hive服务 打开idea&#xff0c;在项目界面中的右边栏找到Database&#…

学术小白如何写好论文引言

文章目录 1.引言写作逻辑1.1 第一段:从现实出发1.2 第二段:文献综述1.3 第三段:引入研究理论和中介变量1.4 第四段:介绍调节变量的概念1.5 第五段&#xff1a;总结 Hello&#xff0c;宝子们&#xff0c;接下来&#xff0c;我们将持续不断更新一系列围绕论文写作的tips建议&…

vue3学习笔记(附加铺垫知识)

Vue3 1.铺垫知识 1.1ES6 默认导出与默认导入&#xff1a; 按需导出与按需导入&#xff1a; 直接导入并执行模块中的代码&#xff1a; 1.2Promise 回调地狱&#xff1a; 基本概念&#xff1a; 使用promise封装自己的读文件方法&#xff1a; 第一步&#xff1a; 第二步&a…

IP地址和MAC地址

1、MAC地址 MAC&#xff08;Media Access Control&#xff0c;介质访问控制&#xff09;地址&#xff0c;或称为物理地址&#xff0c;也叫硬件地址&#xff0c;用来定义网络设备的位置&#xff0c;MAC地址是网卡出厂时设定的&#xff0c;是固定的&#xff08;但可以通过在设备…

二进制安装K8S

阿里巴巴开源镜像站-OPSX镜像站-阿里云开发者社区 (aliyun.com)https://developer.aliyun.com/mirror/所有节点yum源更换为 &#xff0c;按照aliyun给的容器里面的kubenetes源和docker源&#xff0c;当然最好把之前的centos源也换成aliyun的 所有节点安装docker yum install -…

git 环境配置 + gitee拉取代码

好嘛 配环境的时候 老是忘记这个命令行 干脆自己写一个记录一下 也不用搜了 1.先从git官网下载git 安装 2.然后从gitee拉取代码的时候提示 这是因为换了新电脑没有加入新的公钥啦 哎 所以老是记不住命令行 first &#xff1a; git config --global user.name “Your Name” …

windows下上架iOS应用到appstore

windows下上架iOS应用到appstore 背景步骤申请苹果开发者账号创建唯一标示符App IDs申请发布证书申请发布描述文件创建App并填写信息选择证书编译打包上传IPA到App Store提交审核 尾巴 背景 现在由于跨平台技术的兴起&#xff0c;不使用原生技术就能开发出Android和iOS应用。A…

redis cluster集群常见错误问题记录

错误信息一&#xff1a; [ERR] Node 127.0.0.1:6379 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0. 这个报错是因为集群配置信息有被修改后导致的&#xff0c;比如某个节点里的redis.conf配置有变…

儿童节小游戏——HTML+JS实现贪吃蛇

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…