0
点赞
收藏
分享

微信扫一扫

封装第三方组件(四)提取相同代码做成共用函数

雷同代码,就要拿出来做成共用函数

属性

表单的子控件,有很多相同的属性,如果每个组件都写一遍,就太麻烦了,而且也不便于实现统一的维护和增改。

那么怎么办呢?我们可以建立一个 js文件,在里面设置组件的共同的属性。

// control-props.js

/**
 * 基础控件的共用属性
 */
export const baseProps = {
  controlId: { // 101 控件ID,必填
    type: Number,
    default: () => Math.floor((Math.random()*10000000)+1) // 避免必须设置ID的麻烦
  },
  colName: String, // 102 字段名称
  controlType: Number, // 104 控件类型编号
  size: { // 109 medium / small / mini 三选一,不必填
    type: String,
    default: 'mini',
    validator: (value) => {
      // 这个值必须匹配下列字符串中的一个
      return ['medium', 'small', 'mini'].indexOf(value) !== -1
    }
  },
  optionList: { // 选项
    type: Array,
    default: () => []
  },
  clearable: { // 统一设置,是否可清空,默认可以清空
    type: Boolean,
    default: true
  },
  validate_event: { // 统一设置,不必填,输入时是否触发表单的校验
    type: Boolean,
    default: true
  },
  show_word_limit: { // 统一设置,不必填,是否显示输入字数统计 text和area有效
    type: Boolean,
    default: true
  }
}

其他属性用 $attrs 的方式自动传递。

内部成员和事件。

因为 element-plus 把 value 也封装成了 v-model 的形式,所以无法直接绑定组件的属性(modelValue),那么就需要做一个内部变量做中转,这个处理方式也是共用的,可以拿出来放在单独的 js 文件里面。

/**
 * 表单子控件的管理类
 * @param {*} props 组件的属性,获取modelValue和meta属性
 * @param {*} context 上下文获取emit,提交数据
 * @returns {*} value:绑定到组件的值
 * @returns {*} mySubmit:向父组件提交的事件
 */
const controlItemManage = (props, context) => {
  // 用于绑定控件的值。
  const value = debounceRef(props, context)

  // 向父组件提交事件
  const mySubmit = (val) => {
    // 修改 modelValue 属性
    context.emit('update:modelValue', val)
    // 提交 myChange 表单组件需要用,可以得到组件ID和字段名称,
    // 用于区分是哪个组件触发的事件。
    context.emit('my-change', val, props.controlId, props.colName)
  }

  return {
    value,
    mySubmit
  }
}

组件里调用

首先引入两个 js 文件,然后就可以使用了。

import { defineComponent } from 'vue'
// 引入表单子控件的管理类
import controlItemManage from '/ctrlManage/control-item.js'
// 引入组件需要的属性
import { baseProps } from '/ctrlManage/control-props.js'

export default defineComponent({
  name: 'el-form-item-text',
  props: {
    ...baseProps, // 基础属性
    modelValue: [String, Array, Number]
  },
  emits: ['update:modelValue', 'my-change'],
  setup (props, context) {
    return {
      ...controlItemManage(props, context)  // value、mySubmit
    }
  }
})

...的解构方式还是非常好用的。
本来这里打算改成 script setup 的形式的,但是遇到了两个问题。

  1. 属性无法拿出去共用,到目前为止还没有找到方法。
  2. 解构方式不知道怎么改。

这样组件代码就简洁多了,而且也方便维护。

模板里面设置属性就好。

  <el-input
    v-model="value"
    @clear="mySubmit"
    :id="'c' + controlId"
    :name="'c' + controlId"
    :size="size"
    :clearable="clearable"
    :validate_event="validate_event"
    :show-word-limit="show_word_limit"
  >
  </el-input>

像文本、密码这些简单的组件,js部分基本不用写代码了,模板里面只需要设置属性就好,非常简单好维护。

举报

相关推荐

0 条评论