Vue生成动态表单(input,radio,checkbox,select),并动态添加验证规则

定义一个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();
            },
        }

    });

效果图

在这里插入图片描述

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值