一番整理之后,属性方面更简洁了一些,而且也方便了一些,另外也不是太乱了。
集中定义属性
每个控件都需要设置一些属性,那么还是统一管理一下的好,于是设置了一个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 即可。 如果是在封装的表单控件里面使用的话,还需要设置注释掉的那几个属性。因为要告诉表单控件,需要加载的控件类型。
话说,好像不需要响应式。