Vue3组件(14)控件属性的设定

一番整理之后,属性方面更简洁了一些,而且也方便了一些,另外也不是太乱了。

集中定义属性

每个控件都需要设置一些属性,那么还是统一管理一下的好,于是设置了一个js文件来统一管理。


/**
 * 表单子控件需要的属性。
 * * 共用属性部分,基本上每个控件都需要。
 */
export const baseFormProps = {
  controlId: { // 101 控件ID,必填
    type: Number,
    required: true
  },
  colName: String, // 102 字段名称,必填,避免自动绑定
  isClear: Boolean, // 103 连续添加是否清空,必填,避免自动绑定
  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: []
  },
  validate_event: { // 统一设置,不必填,输入时是否触发表单的校验
    type: Boolean,
    default: true
  }
}

/**
 * 多行文本的属性
 */
export const areaProps = {
  show_word_limit: { // 统一设置,不必填,是否显示输入字数统计 text和area有效
    type: Boolean,
    default: true
  },
  rows: { //
    type: Number,
    default: 3
  }
}

/**
 * el-text 单行文本用的属性
 */
export const textProps = {
  show_word_limit: { // 统一设置,不必填,是否显示输入字数统计 text和area有效
    type: Boolean,
    default: true
  },
  clearable: { // 统一设置,不必填,是否显示清空标记
    type: Boolean,
    default: true
  },
  resize: String // 统一设置,不必填, none, both, horizontal, vertical
}

/**
 * 密码的属性
 */
export const passwordProps = {
  show_password: { // 统一设置,不必填,是否显示切换密码图标
    type: Boolean,
    default: true
  }
}

/**
 * 数字的属性
 */
export const numberProps = {
  controls_position: { // 统一设置,不必填,+-号的位置
    type: String,
    default: 'right'
  }
}

/**
 * 滑块的属性
 */
export const sliderProps = {
  input_size: { // 统一设置,不必填,是否显示切换密码图标
    type: String,
    default: 'mini',
    validator: (value) => {
      // 这个值必须匹配下列字符串中的一个
      return ['large', 'medium', 'small', 'mini'].indexOf(value) !== -1
    }
  }
}

分为两个部分:基础属性和扩展属性。

  • 基础属性
    这个是每个控件都需要的属性。

  • 扩展属性
    这个是针对各类控件设计的,比如多行文本框需要设置 rows 属性。

这样的话,方便管理也方便扩展。

UI库的控件需要的其他的属性,可以通过继承的方式来赋值,因为要是一一都设置为props的话,那实在是太麻烦了,想想都头痛。

控件代码更简洁

因为不用一个个属性的绑定,代码要简单不少。

比如文本框的代码

<!--单行文本-->
<template>
  <el-input
    v-model="value"
    @input="mySubmit"
    @blur="myBlur"
    :id="'c' + controlId"
    :name="'c' + controlId"
    :size="size"
    :validate-event="validate_event"
    :show-word-limit="show_word_limit"
    :clearable="clearable"
    :resize="resize"
  >
  </el-input>
</template>
import { defineComponent } from 'vue'
// 引入表单子控件的管理类
import formItemManage from '../controlManage/formItemManage.js'
// 引入组件需要的属性
import { baseFormProps, textProps } from '../controlConfig/formItemMeta.js'

export default defineComponent({
  name: 'el-form-text',
  props: {
    modelValue: String,
    ...baseFormProps, // 基础属性
    ...textProps // 单行文本的属性
  },
  // emits: ['myChange', 'update:modelValue', 'input', 'change', 'blur', 'focus', 'clear'],
  setup (props, context) {
    console.log('props-text', props)

    return {
      ...formItemManage(props, context)
    }
  }
})

简单了不少吧。

  • props
    不用写具体的属性设置了,而是加载js文件,获得基础属性和扩展属性,然后用扩展的方式设置。

这样增加属性也不用改组件的js的代码了。当然模板还要改一下。

  • template
    模板部分,props的属性还是需要手写绑定一下,这个主意是想通过props的默认值的方式来做统一风格的设置。这样既可以保持统一,又可以实现个性设置,增加灵活性。

然后要研究一下验证的问题,不知道差点什么,没有触发el-form的验证功能。

异步的方式注册组件

一般我们都是引入.vue文件,然后注册组件,这样的话组件少还好办,但是组件多了就麻烦了。

怎么办呢?我们可以用vue提供的异步组件的方式来实现批量注册。

import { defineAsyncComponent } from 'vue'

/**
 * 组件里面注册控件用
 * * 文本
 * ** eltext 单行文本、电话、邮件、搜索
 * ** elarea 多行文本
 * ** elurl
 * * 数字
 * ** elnumber 数字
 * ** elrange 滑块
 * * 日期
 * ** eldate 日期、年月、年周、年
 * ** eltime 时间
 * * 选择
 * ** elcheckbox 勾选
 * ** elswitch 开关
 * ** elcheckboxs 多选组
 * ** elradios 单选组
 * ** elselect 下拉选择
 */
const formItemList = {
  // 文本类 defineComponent
  'el-form-text': defineAsyncComponent(() => import('./t-text.vue')),
  'el-form-area': defineAsyncComponent(() => import('./t-area.vue')),
  'el-form-url': defineAsyncComponent(() => import('./t-url.vue')),
  'el-form-password': defineAsyncComponent(() => import('./t-password.vue')),
  // 数字
  'el-form-number': defineAsyncComponent(() => import('./n-number.vue')),
  'el-form-range': defineAsyncComponent(() => import('./n-range.vue')),
  // 日期、时间
  'el-form-date': defineAsyncComponent(() => import('./d-date.vue')),
  'el-form-time': defineAsyncComponent(() => import('./d-time.vue')),
  // 选择、开关
  'el-form-checkbox': defineAsyncComponent(() => import('./s-checkbox.vue')),
  'el-form-switch': defineAsyncComponent(() => import('./s-switch.vue')),
  'el-form-checkboxs': defineAsyncComponent(() => import('./s-checkboxs.vue')),
  'el-form-radios': defineAsyncComponent(() => import('./s-radios.vue')),
  'el-form-select': defineAsyncComponent(() => import('./s-select.vue')),
  'el-form-selwrite': defineAsyncComponent(() => import('./s-selwrite.vue'))
}

/**
 * 动态组件的字典,便于v-for循环里面设置控件
 */
const formItemListKey = {
  // 文本类
  100: formItemList['el-form-area'], // 多行文本
  101: formItemList['el-form-text'], // 单行文本
  102: formItemList['el-form-password'], // 密码
  103: formItemList['el-form-text'], // 电话
  104: formItemList['el-form-text'], // 邮件
  105: formItemList['el-form-url'], // url
  106: formItemList['el-form-text'], // 搜索
  // 数字
  120: formItemList['el-form-number'], // 数组
  121: formItemList['el-form-range'], // 滑块
  // 日期、时间
  110: formItemList['el-form-date'], // 日期
  111: formItemList['el-form-date'], // 日期 + 时间
  112: formItemList['el-form-date'], // 年月
  113: formItemList['el-form-date'], // 年周
  114: formItemList['el-form-date'], // 年
  115: formItemList['el-form-time'], // 任意时间
  116: formItemList['el-form-time'], // 选择固定时间
  // 选择、开关
  150: formItemList['el-form-checkbox'], // 勾选
  151: formItemList['el-form-switch'], // 开关
  152: formItemList['el-form-checkboxs'], // 多选组
  153: formItemList['el-form-radios'], // 单选组
  160: formItemList['el-form-select'], // 下拉
  161: formItemList['el-form-selwrite'], // 下拉多选
  162: formItemList['el-form-select'] // 下拉联动

}

export default {
  formItemList,
  formItemListKey
}

还是统一管理的套路,这样路径有变化,也是只需要改这一个地方就好。

使用方法

 components: {
    ...elFormConfig.formItemList
  },

这样只需要一行就可以实现批量注册了。

模板里还是一样的使用方式

<el-form-text v-model="model.text" v-bind="metaText"/>

meta的最简单设置

由于采用了默认值和继承的方式,所以需要设置的属性大大降低,如果只是单独使用的话,那么可以不设置meta,当然这样的话,直接用element的框架就好。

然后就是需要哪些属性就设置哪些属性就好。和直接使用element的区别在于,select这类的组件要简化一些。

比如 select的使用

<el-form-select
 v-model="model.selectId"
 v-bind="metaSelect"
 @change="myChange"/>

不管需要设置多少属性,选项有多少,模板部分只需要这一行就可以搞定,整个表单的代码就可以简洁很多。

  // 单选组、多选组、下拉的属性
  metaSelect: reactive({
    // controlId: 1160,
    // colName: 'personType',
    // controlType: 160,
    // defaultValue: 1,
    optionList: [
      { value: 1, label: '选项一' },
      { value: 2, label: '选项二' },
      { value: 3, label: '选项三' },
      { value: 4, label: '选项四' },
      { value: 5, label: '选项五' },
      { value: 6, label: '选项六' },
      { value: 7, label: '选项七' }
    ]
  }),

需要的属性可以在这里统一设置,如果是单独使用的话,只需要设置 optionList 即可。
如果是在封装的表单控件里面使用的话,还需要设置注释掉的那几个属性。因为要告诉表单控件,需要加载的控件类型。

话说,好像不需要响应式。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,607评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,047评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,496评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,405评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,400评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,479评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,883评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,535评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,743评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,544评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,612评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,309评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,881评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,891评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,136评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,783评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,316评论 2 342

推荐阅读更多精彩内容