Vue生成动态表单(input,radio,checkbox,select),并动态添加验证规则
定义一个form<el-form :model="letterForm" ref="letterForm" label-width="100px" :rules="formValidateRules" ><div v-for="formItem in formItemList" :key="formItem.id" class="form_item_content"><
·
定义一个form
根据后台配置不同属性,渲染不同的组件。这里写的比较糙,有兴趣的小伙伴可以自行改进。
<el-form :model="letterForm" ref="letterForm" label-width="100px" :rules="formValidateRules">
<div v-for="(formItem,index) in formItemList" :key="formItem.id" class="form_item_content">
<!--单行文本-->
<el-form-item v-if="formItem.dataType == ('varchar' || 'char')"
:label="formItem.fieldText"
:prop="formItem.fieldName">
<el-input v-model="letterForm[formItem.fieldName]"
:placeholder=`请输入${formItem.fieldText}`></el-input>
</el-form-item>
<!--文本域-->
<el-form-item v-if="formItem.dataType == 'textarea'" :label="formItem.fieldText"
:prop="formItem.fieldName">
<el-input
type="textarea"
:rows="2"
:placeholder=`请输入${formItem.fieldText}`
v-model="letterForm[formItem.fieldName]">
</el-input>
</el-form-item>
<!--单选-->
<el-form-item v-else-if="formItem.dataType == 'radio'" :label="formItem.fieldText"
:prop="formItem.fieldName">
<el-radio v-for="(radioItem,radioIndex) in formItem.defaultValue"
:key="radioIndex"
v-model="letterForm[formItem.fieldName]"
:label="radioItem">
{{radioItem}}
</el-radio>
</el-form-item>
<!--多选-->
<el-form-item v-else-if="formItem.dataType == 'checkbox'" :label="formItem.fieldText"
:prop="formItem.fieldName">
<el-checkbox-group v-model="checkedModel['list'+formItem.ext05]">
<el-checkbox v-for="(checkItem,checkIndex) in formItem.defaultValue"
:key="checkIndex"
:label="checkItem">
{{checkItem}}
</el-checkbox>
</el-checkbox-group>
</el-form-item>
<!--下拉选择-->
<el-form-item v-else-if="formItem.dataType == 'select'" :label="formItem.fieldText"
:prop="formItem.fieldName">
<el-select v-model="letterForm[formItem.fieldName]" placeholder="请选择">
<el-option
v-for="(selectItem,selectIndex) in formItem.defaultValue"
:key="selectIndex"
:label="selectItem"
:value="selectItem">
</el-option>
</el-select>
</el-form-item>
</div>
<el-form-item>
<el-button type="primary" @click="submitForm('letterForm')">提交</el-button>
<el-button @click="resetForm('letterForm')">重置</el-button>
</el-form-item>
</el-form>
请求数据,渲染表单,添加对应的验证
这里的checkbox 渲染后赋值有问题,所以用来这种写法。本来想直接把对应的组件对象的默认值赋值成一个空数组作为checkbox group的value绑定(
js:
this.letterForm[formItem.fieldName] = []
页面:
<el-checkbox-group v-model="letterForm[formItem.fieldName]">
<el-checkbox v-for="(checkItem,checkIndex) in formItem.defaultValue"
:key="checkIndex"
:label="checkItem">
{{checkItem}}
</el-checkbox>
</el-checkbox-group>
),当时选中后没有效果,先使用目前这种比较low的方法来实现。有大佬知道知道其中的问题欢迎评论区留言。
//手机号验证回调
const checkMobile = (rule, value, callback) => {
const pattern = /^((0\d{2,3}-\d{7,8})|(1[3576849]\d{9}))$/
if (value !== '') {
if (!pattern.test(value)) {
callback(new Error('请输入正确的电话'))
} else {
callback()
}
}
}
const $vue = new Vue({
el: "#main",
data: {
formItemList: [],//表单字段集合
formValidateRules: {},//表单验证对象
letterForm: {},//表单model
checkedModel: {
list1: [],
list2: [],
list3: [],
list4: [],
}
},
mounted() {
this.getFormList();
},
methods: {
//获取表单字段集合
getFormList() {
const _this = this
$api.get(`getFieldByFormId?formId=${formId}`)
.then(res => {
_this.initLabel(res.data)
_this.initValidateRules(res.data)
_this.$nextTick(() => {
_this.formItemList = res.data
})
console.log(_this.formItemList);
})
.catch(err => {
console.log(err);
})
},
//初始化表单验证对象
initValidateRules(formItemList) {
formItemList.forEach(formItem => {
// this.formData[formItem.fieldName] = ''
let itemRule = []
//如果该字段是必填字段,那么给表单验证规则对象中新增一个对应属性
if (!formItem.isMust) {
//非空验证
itemRule.push({required: true, message: `请输入${formItem.fieldText}`, trigger: 'blur'})
//字符最大长度验证
itemRule.push({
max: formItem.maxLength,
message: `长度不能超过${formItem.maxLength}个字符`,
trigger: 'blur'
})
//如果字段包含email并且需要验证,新增邮箱验证
if (formItem.fieldName.indexOf("email") !== -1) {
itemRule.push({type: 'email', message: '请输入正确的邮箱地址', trigger: ['blur', 'change']})
}
//如果字段包含telephone或者mobile并且需要验证,新增手机号验证
if (formItem.fieldName.indexOf("telephone") !== -1 || formItem.fieldName.indexOf("mobile") !== -1) {
itemRule.push({required: true, validator: checkMobile, trigger: ['blur', 'change']})
}
}
//将验证规则push到表单验证对象
this.formValidateRules[formItem.fieldName] = itemRule
})
console.log("formValidateRules:", this.formValidateRules);
console.log("letterForm:", this.letterForm);
},
//初始化表单数据
initLabel(formItemList) {
let checkIndex = 0
formItemList.forEach(formItem => {
if (formItem.dataType === 'radio') {
formItem.defaultValue = formItem.defaultValue.split(',')
} else if (formItem.dataType === 'checkbox') {
formItem.defaultValue = formItem.defaultValue.split(',')
formItem.ext05 = ++checkIndex
} else if (formItem.dataType === 'select') {
formItem.defaultValue = formItem.defaultValue.split(',')
}
})
},
//写信提交
submitForm(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
//TODO 请求接口
console.log('submit');
} else {
console.log('error submit!!');
return false;
}
});
},
//重置表单
resetForm(formName) {
this.$refs[formName].resetFields();
},
}
});
效果图
更多推荐
已为社区贡献3条内容
所有评论(0)