vue和iview結合動態生成表單實例
在項目中,表單作為用戶輸入占用很重要的一部分,目前的前端框架,基本對表單進行瞭一些簡單的封裝,如果輸入項很多,以iview為例,會有一大堆的類似:
<FormItem label="Input"> <Input v-model="formItem.input" placeholder="Enter something..."></Input></FormItem>
這樣的標簽,現在將用
{//input輸入框 type:'InputNumber', placeholder:"請數量", label:'數量', value:1, props:'num', isRequire:true, emptyTip:'數量不能為空' },
這樣的輸入來簡化,配置表單的生成。
一、構建myform組建
新建myForm.vue文件
1、結合vue和iveiw的框架,根據需求,對表單分一列,兩列,多列展示,需要設置變量cols,表單項前面的文字寬度也不一樣,因此還需設置變量labelWidth,渲染表單(展示你想展示的內容),需設置變量formDatas,最後,用戶完成輸入後還需獲取表單數據,需要設置變瞭formDataModel。到此,配置表單大致需要的變量已基本設置完成。
大致代碼如下:
<Form ref="formValidate" :label-width="labelWidth" :model="formDataModel" class="leftLabel"> <Row :gutter="32"> <Col :span="cols" v-for="(item,index) in formDatas" :key="index"> <myFormItem :schema = "item" :key="index" :formObj="formDatas"></myFormItem> </Col> </Row> </Form>
2、一般情況下每個表單的下面都會有操作,比如確定,取消等,這樣我們可以用slot插入來實現不同引用頁面的功能
<section> <slot name="btnCancel" :cancelFormBtn="cancelForm"><Button type="default">取消</Button></slot> <slot name="btnSave" :saveFormBtn="saveForm"><Button type="primary">確定</Button></slot> </section>
這樣myform組件就大致完成,在上面的myform組建中,有一個myFormItem 的組建,下面我們就來實現myFormItem。
二、構建myFormItem組建
新建myFormItem.vue文件
myFormItem中,由於表單項有很多種,包括input,select,checkBox等,如果在這個組建中用v-if來控制顯示,這樣這個頁面很臃腫,因此,采用函數式組建來和render函數來動態構建不同類型的表單
因此myFormItem組建代碼大致如下:
<my-contrl :schema="schema" :formObj="formObj"></my-contrl>
三、構建函數式組件mycontrl組件
新建myContrl.js文件
函數式組件的大致結構如下,首先根據context中的類型進行分發,然後再用渲染函數渲染出來
function getControl(context){ let {type,label,placeholder,value} = context.props.shema; return {type,label,placeholder,value} } export default{ functional:true, props:{ schema:Object }, render(h,context){ let {type,label,placeholder,value} = getControl(context); return h('FormItem',{ props:{ label:label, }, },[ h(type,{ placeholder:placeholder, value:value, }) ]) } }
中間需註意的小細節:
1、由於一般設置必填項和非必填項的樣式不一致,如果要用到iview裡面的樣式,需要在formItem下加class:‘ivu-form-item-required’,代碼如下:
class:{ 'ivu-form-item-required':isRequire, },
2、如果表單項是select,checkBox等,在select下面會有option屬性,因為都是動態輸入的值,所以,要用render函數動態生成數組
keyValue.map(item=>{ return h(keyData,{ props:{ [keyData==='Option'?'value':keyData==='Button'?'icon':'label']:item.key, } },item.label) })
到此,靜態頁面的渲染也就完成瞭。
四、用戶輸入的時候需要對表單項中進行各種驗證或者邏輯
為瞭實現此功能,一般我們用到vue中的混入,將公用的驗證,邏輯寫到同一個文件中,再將每個表單中單獨的邏輯放到引用這個表單的vue中。
因此在mycontrl.js文件的render函數中,要為每個表單項註冊一個on-change或on-blur事件,然後觸發對應的函數,並且設置此表單的對象的值。
1、設置表單項的值
context.parent.setValue(context.data.attrs.formObj,props,val);
2、判斷是否必填進行操作
if(val==='' || val===null || val.length===0){ context.parent.Validate('rule-empty',`${label}id`,emptyTip); return; }else{ context.parent.ValidateHide('rule-empty',`${label}id`) }
3、規則驗證判斷
for(let r = 0;r<rules.length;r++){ let flag = rules[r].valide(val); if(flag){ context.parent.ValidateHide(`rule-${rules[r].name}`,`${label}id`) }else{ context.parent.Validate(`rule-${rules[r].name}`,`${label}id`,rules[r].tip); break; } } return;
4、邏輯判斷
logicRelation(val)
像類似前面的Validate,ValidateHide,setValue這些函數,都放在混入的js函數中,作為公共函數,而邏輯,規則下的驗證函數就放在瞭每個配置表單的配置項裡面瞭。以上所有的判斷都寫作on-blur或on-change中
五、表單輸入完成獲取表單中的值
這個寫在myForm.vue中
1、在計算屬性中,取得這個表單的項和值
computed:{ formDataModel:function(){ return this.getValue(this.formDatas); } }
2、點擊確定按鈕的時候,將這個值返回到傳入確定按鈕的這個函數中
saveForm(fn,errFn){ let _this = this; if(_this.isValidData(_this.formDatas,_this.formDataModel)){ fn(_this.formDataModel) }else{ _this.$Message.error('表單輸入有誤!請按頁面提示輸入') if(errFn){ errFn() } } }
3、取消按鈕,將值還原,或者是別的需要的操作
cancelForm(type,fn){ if(type==='modify'){ fn() }else if(type==='close'){ this.$emit('closeModel') }else{ this.backDefault(this.defaultValCopy,this.formDatas); } }
六、在要用到表單的頁面使用
<my-form :formData="formDatas" :cols="12" :labelWidth="100"> <template v-slot:btnCancel ="{cancelFormBtn}"> <Button type="default" @click="cancelFormBtn('modify',getlist)">取消</Button> </template> <template v-slot:btnSave ="{saveFormBtn}" > <Button type="primary" @click="saveFormBtn(save)">保存</Button> </template> </my-form>
配置項中的formData格式
[ { type:'InputNumber', placeholder:"Web", label:'Web', value:1, props:'web', isRequire:true, emptyTip:'Web不為空' }, {//select選擇框 type:'Select', placeholder:"請選擇要輸入內容", label:'記錄', data:{ Option:[ {key:'1',label:'記錄'}, {key:'0',label:'不記錄'}, ] }, value:'1', props:'record', isRequire:true, emptyTip:'請選擇', logicRelation:this.isHideKafka }]
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。
推薦閱讀:
- vue如何使用vue slot封裝公共組件
- vue封裝form表單組件拒絕重復寫form表單
- Vue3+Element+Ts實現表單的基礎搜索重置等功能
- vue中實現可編輯table及其中加入下拉選項
- vue+elementui實現動態添加行/可編輯的table