优化 vue 中的二次开发组件的几点细节

背景

之前二次封装 element 组件时,有些细节处理不到位,没有利用好一些特性,本次针对其中的几个问题作出优化。

问题1

二次封装组件时复用 prop 列表

分析与优化

之前拓展组件时,总是完整地重写一遍 prop 列表,其实没必要。可以直接用 v-bind="$attrs" 替代不需要重写的 prop 。比如:

el-button / el-link 等组件想使用图标时,必须手动加上前缀 el-icon-,比较繁琐,就将这些部分重写了;并且还老老实实将所有 prop 重写了一遍,因为不写的话,内部的 el-button 等组件无法接受到外部传入的 prop 值。
但实际上,除开 icon prop,其他 prop 只需要绑定 v-bind="$attrs" , element 组件就能接收到。之前对于 $attrs 的认知错误,以为这个特性只能用于传递 html 元素的自定义属性,其实在这里提到的场景也能使用。此外,vue3 中还将事件监听器也合并到 $attrs,传递起来更加方便。

问题2

减少不必要的组件层级

分析与优化

第二个问题是开发列表组件(比如 cardList 组件用于批量生成卡片,减少重复编写视图结构的工作量)时,总是先把外部组件库的组件封装一层,在此基础上再嵌套一层 list 组件。但其实直接将外部组件库的组件封装到 list 组件里即可,既节省了代码量,同时又减少了文件数量(个人倾向于单文件组件的开发模式),更利于维护项目。

此外,由于舍弃了两层结构,插槽的使用方式也需要调整。

以下使用 el-cardcard-list 举例。

之前的思路
el-card 的二次封装组件中定义插槽的出口,并绑定一些 prop ;然后在 list 组件中通过“插槽穿透+参数过滤”的方式 (只是个人的命名,非官方;之前写过一篇介绍: 传送门,通过 <template> 内部嵌套一层 <slot> 的方式,将业务组件传递给 list 组件的特定内容,经过 card 组件过滤后再批量展示。
比如链接中使用的例子:卡片+行列布局,prop 接收的参数是一个嵌套对象,包含了卡片的参数和布局的参数,每个卡片只会显示自身对象所包含的布局参数,方便批量生成卡片内部的布局。

新的思路将两层结构改为单层结构后,直接在 list 组件内部的 el-card 组件中,定义好插槽出口即可。此处不再需要穿透插槽。

问题3

支持在业务组件中自定义基础组件的样式,或称自定义样式参数

分析与优化

还是拿卡片组件举例,之前将卡片的间距直接写在 list 组件里,不方便动态调整;而如果写在业务组件中,每次都要重写选择器和属性又过于麻烦。因此还是需要基础组件自身有基础样式,同时又必须支持自定义参数。

.dyn-card-list {
  .el-card:nth-child(n + 2) {
    margin-top: 30px; // 设置除第一个卡片外其他卡片的上间距
  }
}

新方案的步骤:

  1. 通过 prop 传递间距的数值
  2. el-card 的 style 属性上绑定 css3 的变量(注意此处是 css3 的自定义变量,而非 sass 等预处理器的自定义变量):
    <!-- 此处省略了其他 prop -->
    <el-card :style="cardGap ? { '--cardGap': cardGap + 'px' } : ''">...</el-card>
    
    ...
    props: {
      ...
      cardGap: {
        type: Number,
        default: 0,
      },
    }
    
posted @ 2022-09-17 19:47  CJc_3103  阅读(276)  评论(0编辑  收藏  举报