在项目中 ,表单作为用户输入占用很重要的一部分 ,目前的前端框架,基本对表单进行了一些简单的封装 ,如果输入项很多 ,以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
}]
以上为个人经验 ,希望能给大家一个参考 ,也希望大家多多支持本站 。
声明:本站所有文章 ,如无特殊说明或标注 ,均为本站原创发布 。任何个人或组织,在未征得本站同意时 ,禁止复制 、盗用 、采集 、发布本站内容到任何网站 、书籍等各类媒体平台 。如若本站内容侵犯了原著者的合法权益 ,可联系我们进行处理 。