vue3组件二次封装Ui处理

news2024/9/21 19:06:25

vue 组件二次封装Ui处理

vue 组件二次封装Ui处理

在Vue开发中,我们常常需要使用UI框架提供的组件。但是UI框架的组件可能并不符合我们的需求,这时候就需要进行二次封装。下面是一些关于Vue组件二次封装Ui处理的技巧:

常规时候咱们使用组件的props、events、slot等属性的传递

子组件代码:

<template>
  <div class="my-input">
    <el-input></el-input>
  </div>
</template>

<script setup>
export default {
  props:[]
}
</script>

<style scoped>
.my-input {
  transition: 0.3s;
}
.my-input:hover,
.my-input:focus-within {
  filter: drop-shadow(0 0 3px rgba(0, 0, 0, 0.3));
}
</style>

父组件使用:

<my-input v-model="value"></my-input>

如果使用props接收弊端:

  1. 基本上组件不会只有一两个属性,属性多的话接收的数据量多,需要写大量的无用代码
  2. 如果存在多级组件嵌套传值,又是重复代码,并且维护性差

$attrs$listeners 解决数据穿透问题

因为vue2和vue3有些不同咱分开讲:

vue2的介绍和使用:

在这里插入图片描述

上面感觉很难懂:简单来说就是**$attrs** 接收传递过来的props的值。**$listeners** 当 inheritAttrs:true 继承除props之外的所有属性;inheritAttrs:false 只继承class属性

vue2的代码:

father.vue 组件:

<template>
   <child :name="name" :age="age" :infoObj="infoObj" @updateInfo="updateInfo" @delInfo="TodelInfo" />
</template>
<script>
    import Child from '../components/child.vue'

    export default {
        name: 'father',
        components: { Child },
        data () {
            return {
                name: 'zhangyangguang',
                age: 24,
                infoObj: {
                    from: '济南',
                    job: 'policeman',
                    hobby: ['reading', 'writing', 'skating']
                }
            }
        },
        methods: {
            updateInfo() {
                console.log('update info');
            },
            TodelInfo() {
                console.log('delete info');
            }
        }
    }
</script>

child.vue 组件:

<template>
    <son :height="height" :weight="weight" @addInfo="addInfo" v-bind="$attrs" v-on="$listeners"  />
    // 通过 $listeners 将父作用域中的事件,传入 grandSon 组件,使其可以获取到 father 中的事件
</template>
<script>
    import Son from '../components/Son.vue'
    export default {
        name: 'child',
        components: { Son },
        props: ['name'],
        data() {
          return {
              height: '183cm',
              weight: '76kg'
          };
        },
        created() {
            console.log(this.$attrs); 
       // 结果:age, infoObj, 因为父组件共传来name, age, infoObj三个值,由于name被 props接收了,所以只有age, infoObj属性
            console.log(this.$listeners); // updateInfo: f, TodelInfo: f
        },
        methods: {
            addInfo () {
                console.log('add info')
            }
        }
    }
</script>

son.vue 组件:

<template>
    <div>
        {{ $attrs }} --- {{ $listeners }}
    <div>
</template>
<script>
    export default {
        ... ... 
        props: ['weight'],
        created() {
            console.log(this.$attrs); // age, infoObj, height 
            console.log(this.$listeners) // updateInfo: f, TodelInfo: f, addInfo: f
            this.$emit('updateInfo') // 可以触发 father 组件中的updateInfo函数
        }
    }
</script>

一般不常用,可读性不是很好。但是组件嵌套层比较深,props很繁琐,可以使用。

vue3的使用和介绍:
 $listeners
在这里插入图片描述

代码:

<template>
  <div class="my-input">
    <el-input v-bind="$attrs"></el-input>
  </div>
</template>

<script setup></script>

<style scoped>
.my-input {
  transition: 0.3s;
}
.my-input:hover,
.my-input:focus-within {
  filter: drop-shadow(0 0 3px rgba(0, 0, 0, 0.3));
}
</style>

直接 通过**$attrs** 接收属性和方法。后面在详细介绍vue3的Attributes

这样到这里已经解决属性和方法的问题了。

解决传值和方法问题,还有一个slot插槽

比如elementPlus的input 有如下插槽:
在这里插入图片描述

初步解决方法:

封装组件里定义对应数量的插槽然后再次传递

<template>
  <div class="my-input">
    <el-input v-bind="$attrs">
      <template #prefix>
        <slot name="prefix"></slot>
      </template>
      <template #suffix>
        <slot name="suffix"></slot>
      </template>
      <template #prepend>
        <slot name="prepend"></slot>
      </template>
      <template #append>
        <slot name="append"></slot>
      </template>
    </el-input>
  </div>
</template>

<script setup></script>

<style scoped>
.my-input {
  transition: 0.3s;
}
.my-input:hover,
.my-input:focus-within {
  filter: drop-shadow(0 0 3px rgba(0, 0, 0, 0.3));
}
</style>

这里定义了四个插槽然后再次传递,确实解决了插槽问题。但是使用的组件不一定会使用全部的插槽。如果使用一个那咱们封装的组件就把其他插槽给传递了过去。这样很不保险,并且也不对

解决思路:父级传递几个插槽,咱就传递几个给子组件,不全部传递

进阶解决方法:使用$slots

在这里插入图片描述

也就是说**$slots**可以获取父级组件传递的插槽。

vue3代码:

<template>
  <div class="my-input">
    <el-input v-bind="$attrs">
      <template v-for="(val, name) in $slots" #[name]="slotData">
        <slot :name="name" v-bind="slotData || {}"></slot>
      </template>
    </el-input>
  </div>
</template>

<script>
export default {
  created() {
    console.log(this.$slots);
  },
};
</script>

<style scoped>
.my-input {
  transition: 0.3s;
}
.my-input:hover,
.my-input:focus-within {
  filter: drop-shadow(0 0 3px rgba(0, 0, 0, 0.3));
}
</style>

这样就是父级传递啥那就传递啥插槽。到此解决了插槽问题。

到这里还有个最难的**ref 问题:**

因为ref只能作用于当前无法作用到孙组件

对于ref传递问题vue无法解决。但是咱可以换一个思路。使用ref无非是为了使用孙组件暴露的一些方法。那咱就可以吧孙组件的方法提取到子组件

说白了吧孙组件的方法提取到当前实例

代码:

<template>
  <div class="my-input">
    <el-input ref="inp" v-bind="$attrs">
      <template v-for="(val, name) in $slots" #[name]="slotData">
        <slot :name="name" v-bind="slotData || {}"></slot>
      </template>
    </el-input>
  </div>
</template>

<script>
export default {
  created() {
    console.log(this.$slots);
  },
  mounted() {
    console.log(this.$refs.inp);
    const entries = Object.entries(this.$refs.inp);
    for (const [key, value] of entries) {
      this[key] = value;
    }
  },
};
</script>

<style scoped>
.my-input {
  transition: 0.3s;
}
.my-input:hover,
.my-input:focus-within {
  filter: drop-shadow(0 0 3px rgba(0, 0, 0, 0.3));
}
</style>

这样就完美解决了组件的Ui封装。

以上是一些关于Vue组件二次封装Ui处理的技巧。通过二次封装,我们可以更好地满足我们的需求,提高开发效率。

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

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

相关文章

深元AI盒子在矿山安全生产中实现皮带跑偏、异物、煤流量、大块煤等识别

摘要&#xff1a;随着技术的发展&#xff0c;矿山安全生产已经从传统的人工监测逐步转向现代化智能化。本文旨在探讨矿山安全生产AI盒子在皮带跑偏、异物、煤流量和大块煤之外的功能&#xff0c;以期进一步提高矿山生产的安全性和效率。 正文&#xff1a; 一、引言 矿山安全生…

【获奖案例巡展】信创先锋之星——中信证券基于国产图数据库构建企业图谱的应用实践

为表彰使用大数据、人工智能等基础软件为企业、行业或世界做出杰出贡献和巨大创新的标杆项目&#xff0c;星环科技自2021年推出了“新科技 星力量” 星环科技科技实践案例评选活动&#xff0c;旨在为各行业提供更多的优秀产品案例&#xff0c;彰显技术改变世界的力量&#xff0…

vue2、vue3实现暗黑模式

1、序言 elementPlus、naive UI这些UI组件里面封装好了暗黑模式&#xff0c;直接使用相关api即可实现暗黑模式切换功能&#xff0c;而elementUI没有封装好&#xff0c;我们可以看看elementPlus、naive UI如何实现暗黑模式&#xff0c;然后在elementUI中模仿&#xff0c;从而实现…

【C++】模板初识

C模板初识 1.泛型编程2.函数模板2.1.函数模板概念2.2.函数模板格式2.3.函数模板使用的原理2.4.函数模板的实例化2.5.模板参数的匹配原则 3.类模板3.1.类模板格式3.2.类模板的实例化 1.泛型编程 在实际编程中&#xff0c;经常会用到交换函数。比如有整型值的交换&#xff0c;浮…

Nacos 鉴权系统源码讲解

目录 1. 介绍 2. Nacos SPI 鉴权机制 3. 后台管理 / HTTP 接口鉴权 4. 客户端 / GRPC 接口鉴权 1. 介绍 鉴权功能默认没有开启&#xff0c;开启后的效果就是 Nacos 的接口需要用户登录并且具有权限才能调用该接口。例如注册实例、发布配置等。 鉴权也就是 我是谁、我能干…

探讨接口测试颗粒度

偶然间在论坛上看到一个帖子&#xff0c;帖子内容如下&#xff1a; 假设现在有一个新增商品的接口&#xff0c;返回的参数中有新增商品的 id&#xff08;每次返回的 id 都不一样&#xff09;、success&#xff08;判断是否成功&#xff0c;0 失败 1 成功&#xff09; 1. 接口…

代码随想录之对称二叉树

本内容来自代码随想录 使用后序遍历。 class Solution { public:bool traversal(TreeNode* left,TreeNode* right){//处理空节点情况if (left nullptr && right ! nullptr) return false;else if (left ! nullptr && right nullptr) return false;else if …

Python人工智能之混合高斯模型运动目标检测详解分析

搬运工项目&#xff0c;换个平台纪录&#xff0c;之前的广告太多 运动目标检测是计算机视觉领域中的一个重要内容&#xff0c;其检测效果将会对目标跟踪与识别造成一定的影响&#xff0c;本文将介绍用Python来进行混合高斯模型运动目标检测&#xff0c;感兴趣的朋友快来看看吧 …

4.2寸黑白红TFT电子标签【基站版】

ESL_TFT_4.2_V4 产品参数 产品型号 ESL_TFT_4.2_V4 尺寸(mm) 101.7*84.4*6.5mm 显示技术 TFT反射式 显示区域(mm) 84.8(H) * 63.6(V) 分辨率(像素) 400*300 像素尺寸(mm) 0.212x0.212 显示颜色 黑/白/红 视觉角度 45/45/60/60 工作温度 -20-70℃ 产品重量…

Spring6从入门到精通 第一章 带你玩转Spring

这里写目录标题 一 Spring框架产生的原因二 Spring6配置的关键环节 一 Spring框架产生的原因 传统的JavaWeb存在着耦合度较高的问题&#xff0c;而且实现完整的的MVC三层架构&#xff0c;开发成本过大&#xff0c;因此出现了Spring这个轻量级的开发框架&#xff0c;相当于建筑里…

C++初阶之命名空间的使用

目录 前言 命名空间的介绍 1.1 命名空间的定义 1.2 命名空间的使用 C输入&输出 总结&#xff1a; 前言 今天小编就给大家带来C的相关内容了&#xff0c;相对于C语言而言C的语法会比较复杂一点点&#xff0c;但是我相信大家通过自己的努力&#xff0c;也会很快的上手…

使用AIDEGen进行AOSP开发

什么是AIDEGen AIDEGen&#xff0c;大概是“Android IDE (helper) Generator”的简写&#xff0c;是 AOSP 源代码树中的一个工具&#xff0c;它允许从 Android Studio 等通常仅为非平台应用程序开发配置的 IDE 中处理系统应用程序。 AIDEGen 旨在自动化项目设置过程&#xff…

计算机视觉 | 八斗人工智能 (上)

目录 数字图像像素和分辨率灰度、通道和对比度其他概念 插值算法上采样和下采样的概念1. 最邻近插值2.双线性插值&#xff08;最常用&#xff09;3.双三次插值 直方图均衡化1. 灰度图直方图均衡化2. 彩色图直方图均衡化 数字图像 像素和分辨率 像素&#xff1a; 像素是分辨率…

智能营销服务性能提升2倍关键秘诀?就是亚马逊云科技

随着数字化进程加快和B2B商业市场竞争的白热化&#xff0c;通过挖掘数据“黄金”提升投资回报比与市场竞争力的智能营销&#xff0c;正成为B2B营销的热门风口。 但企业在获得更精准、更智能营销服务的同时&#xff0c;也不得不面临来自海量数据的搜寻以及数据实时更新等方面的…

Golang gorm

GORM 指南 | GORM - The fantastic ORM library for Golang, aims to be developer friendly. 一 对多入门 比如要开发cmdb的系统&#xff0c;无论是硬件还是软件。硬件对应的就是对应的哪个开发在用。或者服务对应的是哪个业务模块在使用&#xff0c;或者应用谁在使用。那么这…

【CXL】在gem5中跑一个实际的应用程序——Viper KV存储

有了CXL扩展内存&#xff0c;自然是要在DRAMCXL扩展内存上跑跑实际的应用程序&#xff0c;看看和DRAM传统磁盘有什么区别。 实际的应用程序其实就是一些工业界部署使用的&#xff0c;比如数据库、深度学习训练项目等等。本文主要找到一个KV存储Viper&#xff0c;搭建并进行简单…

水电设计院信息管理系统1.0

水电设计公司信息管理系统软件使用说明书 代码太多就不贴了&#xff0c;请在我的资源里下载&#xff0c;已部署在企业进行试运行。https://download.csdn.net/download/weixin_44735475/87704302 目录 1.引言 1 2.项目背景 1 3.系统功能 2 3.1系统功能 2 3.2系统性能 2 3.3系…

Python GUI自动化神器pyautogui,精准识别图片并自动点赞(32)

小朋友们好&#xff0c;大朋友们好&#xff01; 我是猫妹&#xff0c;一名爱上Python编程的小学生。 欢迎和猫妹一起&#xff0c;趣味学Python。 今日主题 你听过GUI自动化吗&#xff1f; GUI自动化就是用软件模拟鼠标和键盘的操作。 提到Python GUI自动化&#xff0c;不…

Flink State 笔记帖

1 State 分类 Operator State 主要用在Source、Sink等没有key分布的位置。 Keyed State 用在keyBy后的KeyedStream里&#xff0c;每个存储状态与一个key想关联。 ValueState ListState MapState ReducingState AggeratingState 2 State Backend StateBackend分类 HashMa…

JVM之JDK 监控和故障处理工具总结

JDK 命令行工具 这些命令在 JDK 安装目录下的 bin 目录下&#xff1a; jps (JVM Process Status&#xff09;: 类似 UNIX 的 ps 命令。用于查看所有 Java 进程的启动类、传入参数和Java 虚拟机参数等信息&#xff1b;jstat&#xff08;JVM Statistics Monitoring Tool&#x…