Vue 使用技巧:优雅的进行二次封装 UI 库组件

这篇具有很好参考价值的文章主要介绍了Vue 使用技巧:优雅的进行二次封装 UI 库组件。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。



文章来源地址https://www.toymoban.com/news/detail-428086.html



前提概要:

作为一个前端搬砖工程师经常需要搬砖,封装一些第三方组件,在添加新的属性、插槽、事件时候就会想应该怎么去保留,向外抛出封装原本第三方组件提供的属性、插槽、事件;但是如果是一个个属性和事件以及插槽进行重新声明定义,虽然也是可行的,但是未免也太过于麻烦了,并且这种做法在升级了原本依赖的 UI 库后某些新增或者 break-change 的时候就会发生不明所以的 bug 了。

因此这篇文章就简单的介绍怎么分别来优雅的保留着第三方 UI 库组件原提供的属性(Attributes)、插槽(Slots)和自定义事件(Events),提高生产力效率和代码质量!





一、属性【Attributes】:

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

inheritAttrs:默认情况下父作用域的不被认作 props 的 attribute 绑定 (attribute bindings) 将会“回退”且作为普通的 HTML attribute 应用在子组件的根元素上,也就是下面例子的 MyButton 组件上面也会存在这些想要透传的属性,这可能不会总是符合预期行为。因此此时需要通过设置inheritAttrsfalse,将 Vue.js 的这个默认行为给去掉。而通过实例 的$attrs可以让这些透传的 attribute 生效,且通过v-bind显性的绑定到非根元素第三方 UI 库的组件上了。

// MyButton.vue

<template>
  <a-button v-bind="$attrs" >
    <slot />
  </a-button>
</template>
<script> 
  export default { 
    inheritAttrs: false,
  }
</script>





二、自定义事件【Events】:

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

需要留意:如果既使用了v-on="$listeners"进行转发事件,并且二次封装的组件内也对原 UI 库组件的事件进行监听调用,此时事件会触发两次,需要注意这个问题!

// MyInput.vue

<template>
  <a-input v-bind="$attrs" v-on="$listeners" />
</template>
<script> 
  export default { 
    inheritAttrs: false,
  }
</script>





三、插槽【Slots】:

$slots:普通插槽比较好理解,使用$slots这个变量拿到非作用域的插槽分发内容,然后循环渲染对应的普通具名插槽,这样就能够直接打通封装组件的插槽和第三方组件提供的原插槽;

$scopedSlots:作用域插槽则绕了一圈,使用了一个插槽的语法糖(具名插槽的缩写)并且结合着动态插槽名的用法;循环$scopedSlots并且插入到第三方组件提供的原作用域插槽位置,在里面才创建封装组件自己的作用插槽位置和传递对应的参数,间接打通了作用域插槽的通道。

// MyTable.vue

<template>
  <a-table v-bind="$attrs" v-on="$listeners">
    <!-- 普通插槽 -->
    <slot v-for="(_, slotName) in $slots" :name="slotName" :slot="slotName"/>

    <!-- 作用域插槽 -->
    <template v-for="(_, scopeSlotName) in $scopedSlots" #[scopeSlotName]="scope" >
      <slot :name="scopeSlotName" v-bind="scope" />
    </template>
  </a-table>
</template>
<script>
  export default {
    inheritAttrs: false,
  };
</script>





四、额外加餐

大家应该都知道上面描述主要都是 Vue 2.x 的场景(毕竟现在 2.x 还是在市场上占用不少的份额的嘛),在 Vue 3.x 当中有些 API 是有所调整的,因此这里也简单讲述下 Vue 3.x 的变动调整,主要还是一些组件实例的属性之间的合并。

$attrs 与 $listeners 合并

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

// MyButton.vue

<template>
  <a-button v-bind="$attrs" >
    <slot />
  </a-button>
</template>
<script> 
  export default { 
    inheritAttrs: false,
  }
</script>
<template>
  <my-button size="small" @click="handleClickEvent" >
    这是二次封装的按钮组件
  </my-button>
</template>
<script setup>
  const handleClickEvent = () => {
    // TODO:xxxx
  }
</script>

$slot 与 $scopedSlots 合并

同样,在 Vue 3.x 当中取消了作用域插槽$scopedSlots的属性,将所有插槽都统一在$slots当中,因此在 Vue 3.x 当中最简单粗暴的方法就是直接无分默认插槽、具名插槽和作用域插槽进行统一的处理。

// MyTable.vue

<template>
  <a-table v-bind="$attrs">
    <template v-for="(_, scopeSlotName) in $slots" #[scopeSlotName]="scope" >
      <slot :name="scopeSlotName" v-bind="scope" />
    </template>
  </a-table>
</template>
<script>
  export default {
    inheritAttrs: false,
  };
</script>





参考资料:

相关知识参考资料:

  • 透传 Attributes | Vue.js:https://cn.vuejs.org/guide/components/attrs.html#v-on-listener-inheritance
  • 组件实例 $attrs | Vue.js:https://cn.vuejs.org/api/component-instance.html#attrs
  • 其他杂项选项 inheritattrs | Vue.js:https://cn.vuejs.org/api/options-misc.html#inheritattrs
  • 插槽 Slots | Vue.js:https://cn.vuejs.org/guide/components/slots.html
  • 组件实例 $slots | Vue.js:https://cn.vuejs.org/api/component-instance.html#slots
  • $listeners在vue3中使用-CSDN博客:https://blog.csdn.net/qq_41068783/article/details/118324967
  • Vue3.0破坏性变化----$slots:http://events.jianshu.io/p/d9c4937812cf



到了这里,关于Vue 使用技巧:优雅的进行二次封装 UI 库组件的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • element ui中el-tabs 标签页使用技巧

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 当我们使用el-tabs不要按照固化的思路去写每一页的具体内容,可以通过放在el-tabs外部,相同内容,来让代码更简洁 提示:以下是本篇文章代码,下面案例可供参考 提示:这里简单的介绍了一个el-tabs的使用

    2024年02月16日
    浏览(48)
  • 深度学习技巧应用32-在YOLOv5模型上使用TensorRT进行加速的应用技巧

    大家好,我是微学AI,今天给大家介绍一下深度学习技巧应用32-在YOLOv5模型上使用TensorRT进行加速的应用技巧,TensorRT是NVIDIA公司提供的一个深度学习推理(inference)优化器和运行时库。它专门为生产环境下的高性能深度学习推理提供优化支持。TensorRT可以加速深度学习模型在

    2024年02月02日
    浏览(46)
  • Excel小技巧,使用函数(INDEX+MATCH)快速进行条件查询

    目录 Excel小技巧,使用函数(INDEX+MATCH)快速进行条件查询 1、例如:快速查找下图右边同学的总分  2、在条件查询区域,总分单元格中输入函数【=INDEX(E:E,MATCH(H2,A:A,0))】即可  3、INDEX(E:E  函数为查找结果所在列,MATCH(H2,A:A,0)函数中H2为查找值,A:A为查找所在列,0为精确匹配

    2024年02月10日
    浏览(72)
  • vue2.x 二次封装element ui 中的el-dialog

    在做后台管理系统的时候,dialog组件是我们使用频率比较高的组件,但是有一些需求现有的组件是不满足的。因此会需要我们做二次封装。 组件本身的属性我们保留,只需要根据需求添加,然后在使用的时候props去拿取使用就可以了。 本次遇到的问题是如何在父组件去控制

    2024年02月07日
    浏览(59)
  • element ui 表格组件与分页组件的二次封装 【扩展】vue中的render函数

    目录 效果图  组件封装  parseTime函数 debounce 函数 render通用渲染模版 页面使用 【扩展】vue 函数式组件 函数式组件特点: 函数式组件的优点: 【扩展】vue中的render函数 一、初步认识render函数 二、为什么使用render函数 三、render函数的解析 【扩展】添加操作栏显示权限 结构

    2024年02月09日
    浏览(83)
  • vue3 基于element plus对el-pagination进行二次封装

    在vue3项目中,如果每个列表页都敲一遍分页方法,显然是不合理的,那么,下面我将基于element plus对el-pagination进行二次封装,使用vue3语法糖格式,废话不多说,开干。

    2024年02月12日
    浏览(48)
  • web前端之使用弹性和外边距进行网页布局、非常有用的小技巧、flex、margin、auto

    图中效果只需要flex和margin便可以实现。 1、d_f: display: flex; 2、fw_w: flex-wrap: wrap; 3、m_a: margin: auto; 4、ml_a: margin-left: auto; 5、mr_a: margin-right: auto; 3、item类名比较特殊,所以单独定义,涉及到变量,不属于公共样式 4、其他类名基本是见名知意,不做过多叙述

    2024年02月20日
    浏览(57)
  • 【Vue技巧】Vue2和Vue3组件上使用v-model的实现原理

    ChatGPT4.0国内站点,支持GPT4 Vision 视觉模型:海鲸AI 在Vue中, v-model 是一个语法糖,用于在输入框、选择框等表单元素上创建双向数据绑定。当你在自定义组件中实现 v-model 功能时,你需要理解它背后的原理: v-model 实际上是一个属性和一个事件的简写。 在 Vue 2.x 中, v-mode

    2024年01月15日
    浏览(61)
  • vue+element-ui el-table组件二次封装实现虚拟滚动,解决数据量大渲染DOM过多而卡顿问题

    某些页面不做分页时,当数据过多,会导致页面卡顿,甚至卡死 一、固定一个 可视区域 的大小并且其大小是不变的,那么要做到性能最大化就需要尽量少地渲染 DOM 元素,而这个最小值也就是可视范围内需要展示的内容,而可视区域之外的元素均可以不做渲染。 二、如何计

    2024年02月10日
    浏览(64)
  • 前端开发小技巧 - 【Vue3 + TS】 - 在 TS + Vue3 中使用 Pinia,实现 Pinia 的持久化,优化Pinia(仓库统一管理)

    ts 中使用 pinia 和 Vue3 基本一致,唯一的不同点在于,需要根据接口文档给 state 标注类型,也要给 actions 标注类型; 以下都是 组合式API 的写法, 选项式API 的写法大家可以去官网看看; Pinia; 持久化插件 - pinia-plugin-persistedstate; 目标文件: src/types/user.d.ts (这里以 user.d.t

    2024年04月09日
    浏览(55)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包