一番整理之后英染,屬性方面更簡潔了一些揽惹,而且也方便了一些,另外也不是太亂了税迷。
集中定義屬性
每個控件都需要設(shè)置一些屬性永丝,那么還是統(tǒng)一管理一下的好,于是設(shè)置了一個js文件來統(tǒng)一管理箭养。
/**
* 表單子控件需要的屬性慕嚷。
* * 共用屬性部分,基本上每個控件都需要毕泌。
*/
export const baseFormProps = {
controlId: { // 101 控件ID喝检,必填
type: Number,
required: true
},
colName: String, // 102 字段名稱,必填撼泛,避免自動綁定
isClear: Boolean, // 103 連續(xù)添加是否清空挠说,必填,避免自動綁定
controlType: Number, // 104 控件類型編號愿题,必填损俭,識別表單子控件的類型
size: { // 109 medium / small / mini 三選一,不必填
type: String,
default: 'mini',
validator: (value) => {
// 這個值必須匹配下列字符串中的一個
return ['medium', 'small', 'mini'].indexOf(value) !== -1
}
},
optionList: { // 備用選項(xiàng)
type: Array,
default: []
},
validate_event: { // 統(tǒng)一設(shè)置潘酗,不必填杆兵,輸入時是否觸發(fā)表單的校驗(yàn)
type: Boolean,
default: true
}
}
/**
* 多行文本的屬性
*/
export const areaProps = {
show_word_limit: { // 統(tǒng)一設(shè)置,不必填仔夺,是否顯示輸入字?jǐn)?shù)統(tǒng)計(jì) text和area有效
type: Boolean,
default: true
},
rows: { //
type: Number,
default: 3
}
}
/**
* el-text 單行文本用的屬性
*/
export const textProps = {
show_word_limit: { // 統(tǒng)一設(shè)置琐脏,不必填,是否顯示輸入字?jǐn)?shù)統(tǒng)計(jì) text和area有效
type: Boolean,
default: true
},
clearable: { // 統(tǒng)一設(shè)置缸兔,不必填日裙,是否顯示清空標(biāo)記
type: Boolean,
default: true
},
resize: String // 統(tǒng)一設(shè)置,不必填惰蜜, none, both, horizontal, vertical
}
/**
* 密碼的屬性
*/
export const passwordProps = {
show_password: { // 統(tǒng)一設(shè)置昂拂,不必填,是否顯示切換密碼圖標(biāo)
type: Boolean,
default: true
}
}
/**
* 數(shù)字的屬性
*/
export const numberProps = {
controls_position: { // 統(tǒng)一設(shè)置抛猖,不必填政钟,+-號的位置
type: String,
default: 'right'
}
}
/**
* 滑塊的屬性
*/
export const sliderProps = {
input_size: { // 統(tǒng)一設(shè)置路克,不必填樟结,是否顯示切換密碼圖標(biāo)
type: String,
default: 'mini',
validator: (value) => {
// 這個值必須匹配下列字符串中的一個
return ['large', 'medium', 'small', 'mini'].indexOf(value) !== -1
}
}
}
分為兩個部分:基礎(chǔ)屬性和擴(kuò)展屬性养交。
基礎(chǔ)屬性
這個是每個控件都需要的屬性。擴(kuò)展屬性
這個是針對各類控件設(shè)計(jì)的瓢宦,比如多行文本框需要設(shè)置 rows 屬性碎连。
這樣的話,方便管理也方便擴(kuò)展驮履。
UI庫的控件需要的其他的屬性鱼辙,可以通過繼承的方式來賦值,因?yàn)橐且灰欢荚O(shè)置為props的話玫镐,那實(shí)在是太麻煩了倒戏,想想都頭痛。
控件代碼更簡潔
因?yàn)椴挥靡粋€個屬性的綁定恐似,代碼要簡單不少杜跷。
比如文本框的代碼
<!--單行文本-->
<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, // 基礎(chǔ)屬性
...textProps // 單行文本的屬性
},
// emits: ['myChange', 'update:modelValue', 'input', 'change', 'blur', 'focus', 'clear'],
setup (props, context) {
console.log('props-text', props)
return {
...formItemManage(props, context)
}
}
})
簡單了不少吧。
- props
不用寫具體的屬性設(shè)置了矫夷,而是加載js文件葛闷,獲得基礎(chǔ)屬性和擴(kuò)展屬性,然后用擴(kuò)展的方式設(shè)置双藕。
這樣增加屬性也不用改組件的js的代碼了淑趾。當(dāng)然模板還要改一下。
- template
模板部分忧陪,props的屬性還是需要手寫綁定一下扣泊,這個主意是想通過props的默認(rèn)值的方式來做統(tǒng)一風(fēng)格的設(shè)置。這樣既可以保持統(tǒng)一嘶摊,又可以實(shí)現(xiàn)個性設(shè)置延蟹,增加靈活性。
然后要研究一下驗(yàn)證的問題更卒,不知道差點(diǎn)什么等孵,沒有觸發(fā)el-form的驗(yàn)證功能。
異步的方式注冊組件
一般我們都是引入.vue文件蹂空,然后注冊組件俯萌,這樣的話組件少還好辦,但是組件多了就麻煩了上枕。
怎么辦呢咐熙?我們可以用vue提供的異步組件的方式來實(shí)現(xiàn)批量注冊。
import { defineAsyncComponent } from 'vue'
/**
* 組件里面注冊控件用
* * 文本
* ** eltext 單行文本辨萍、電話棋恼、郵件返弹、搜索
* ** elarea 多行文本
* ** elurl
* * 數(shù)字
* ** elnumber 數(shù)字
* ** elrange 滑塊
* * 日期
* ** eldate 日期、年月爪飘、年周义起、年
* ** eltime 時間
* * 選擇
* ** elcheckbox 勾選
* ** elswitch 開關(guān)
* ** 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')),
// 數(shù)字
'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')),
// 選擇师崎、開關(guān)
'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'))
}
/**
* 動態(tài)組件的字典默终,便于v-for循環(huán)里面設(shè)置控件
*/
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'], // 搜索
// 數(shù)字
120: formItemList['el-form-number'], // 數(shù)組
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'], // 選擇固定時間
// 選擇犁罩、開關(guān)
150: formItemList['el-form-checkbox'], // 勾選
151: formItemList['el-form-switch'], // 開關(guān)
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'] // 下拉聯(lián)動
}
export default {
formItemList,
formItemListKey
}
還是統(tǒng)一管理的套路齐蔽,這樣路徑有變化,也是只需要改這一個地方就好床估。
使用方法
components: {
...elFormConfig.formItemList
},
這樣只需要一行就可以實(shí)現(xiàn)批量注冊了含滴。
模板里還是一樣的使用方式
<el-form-text v-model="model.text" v-bind="metaText"/>
meta的最簡單設(shè)置
由于采用了默認(rèn)值和繼承的方式,所以需要設(shè)置的屬性大大降低丐巫,如果只是單獨(dú)使用的話谈况,那么可以不設(shè)置meta,當(dāng)然這樣的話鞋吉,直接用element的框架就好鸦做。
然后就是需要哪些屬性就設(shè)置哪些屬性就好。和直接使用element的區(qū)別在于谓着,select這類的組件要簡化一些泼诱。
比如 select的使用
<el-form-select
v-model="model.selectId"
v-bind="metaSelect"
@change="myChange"/>
不管需要設(shè)置多少屬性,選項(xiàng)有多少赊锚,模板部分只需要這一行就可以搞定治筒,整個表單的代碼就可以簡潔很多。
// 單選組舷蒲、多選組耸袜、下拉的屬性
metaSelect: reactive({
// controlId: 1160,
// colName: 'personType',
// controlType: 160,
// defaultValue: 1,
optionList: [
{ value: 1, label: '選項(xiàng)一' },
{ value: 2, label: '選項(xiàng)二' },
{ value: 3, label: '選項(xiàng)三' },
{ value: 4, label: '選項(xiàng)四' },
{ value: 5, label: '選項(xiàng)五' },
{ value: 6, label: '選項(xiàng)六' },
{ value: 7, label: '選項(xiàng)七' }
]
}),
需要的屬性可以在這里統(tǒng)一設(shè)置,如果是單獨(dú)使用的話牲平,只需要設(shè)置 optionList 即可堤框。
如果是在封裝的表單控件里面使用的話,還需要設(shè)置注釋掉的那幾個屬性纵柿。因?yàn)橐嬖V表單控件蜈抓,需要加載的控件類型。
話說昂儒,好像不需要響應(yīng)式沟使。