UI 组件的二次封装是指,在基础 UI 库的组件上进行自定义封装,以实现更贴合业务需求的功能和样式。通过二次封装,可以增强组件的复用性、便捷性和一致性,简化业务代码,同时降低后续维护成本。
二次封装基于对原有组件的拓展和定制,一般使用 组合 和 继承 的方式实现。具体实现时,可以利用基础 UI 组件库(如 Element Plus、Vant、Ant Design 等)中的现有组件,通过添加额外的属性、方法或样式,实现业务层面所需的定制功能。
核心思想包括:
1、组合和继承:基于已有组件,通过组合或继承来实现新的组件功能。
2、属性代理:将原有组件的属性透传到封装组件,以保持原组件的功能。
3、事件透传:将用户操作的事件传递给外部调用者,支持外部绑定事件处理。
4、样式定制:通过样式扩展或修改,实现特定样式需求。
5、业务逻辑注入:通过自定义逻辑封装特定的业务逻辑,比如权限控制、数据校验、异步加载等。
1、对属性和事件的传递
举个 ,对 Element-plus 的 el-input 进行处理。
在 App.vue 中:
{}" v-model="defaultValue" />
在 MyInput.vue 中:
使用 $attrs 获取父组件传递的数据,展示为:
但当我们在 自定义组件 内部声明同名属性时:
展示如下:
这个现象是合理的,声明这个属性,说明我们接下来需要使用它做一些额外的处理,对组件本身是有意义的。而没有声明的数据,就汇总到 $attrs 中,可以将这些属性透传给 原始组件 本身。
如下:
对此可以实现,将传递过来的、无需额外更改的属性和方法,透传到 UI 库组件本身。
2、对 插槽(slot)进行处理
在 App.vue 中,传递两个插槽内容。
prepend
append
在 MyInput 组件中:
展示如下,父组件将插槽内容传递给子组件。
3、对 ref 的传递(!important)
虽然在某些特殊的场景下需要使用 ref,但是不建议对 ref 进行传递,那如何处理呢?
在父组件中获取子组件的对象,无非是使用其方法和属性,那就将这些属性传递出去。
App.vue
MyInput.vue
在 App.vue 中调用子组件的 focus 方法:
以此实现,父组件调用子组件的方法。