【elementUi】关于el-form使用自定义校验规则的传参问题

需求:在很多时候,我们的form表单并不是一个个写出来的,而是通过数据遍历渲染的,所以绑定的prop值 model值  rule值等等都不是常规的写法

1.常规

常规的写法:

 

 

 绑定的数据格式:

 

 

 但是现在,有很多输入表单,我们不会一个一个去写,而是通过数据了渲染(正应了VUE数据驱动试图?)

2.需要的效果:

 

由于布局高度相似,所以我们可以考虑循环。

先构思数据应该是什么样的,每一个el-form-item会包含它的绑定值v-model,规则rules,placeholder,甚至还有clearable  disabled等属性

 

 

 

 然后通过数据去构建视图

 

 

 今天的重点是校验规则。由于写法不同平常,所以为每个form-item单独配置校验规则  :rules="item.rules"

有余自定义的校验规则可以放在当前的vue文件中

比如:

 

 

 然后在规则中直接引用

 

 

 但是这样校验规则接没有办法复用,我们可以把所有的校验规则提取成公共的JS文件,export出去,在需要用的vue文件中import进来,在对应的rules上像上边一样使用

这样最大程度的解耦可以服用,但也出现问题,比如本文中的需求,所绑定的v-model的值是children里的nodel  自定义规则的参数value并不能读取到该值

所以我这里想到通过bind传递this,

 

 

 

 

 

 这里为什么写的这么麻烦?我的初衷是通过bind绑定到this,第二个参数直接传递所需要的数据,但是不知道为什么,传this可以读取到,读取再深一点this.boxData或者更深就读不到了

其实在this上年是可以看到具体属性的。知道的还请不吝赐教

所以这里我就这么传参数了   validPercent.bind(this, this, 0, 0)

第一个参数this: 绑定到this

第二个参数this:传递的数据

第三个参数0:该数据所处于boxData的第一层级的index

第四个参数0:该数据所处于boxData的第二层级的index

这两个参数都是为了方便在校验规则里取到对应的value值,这样就达到了传参的目的,思路是这样,但由于上边说的问题,应该还可以精简

 

 

 

插曲: 单个可以执行校验,点击确定按钮的时候无法校验,没有错误提示

有警告

 

 

 只要随便绑定一个model就可以了

 

 

 

 

 

 3.代码:

<template>
    <div class="outerDiv">
        <div class="content">
            <div class="form">
                <el-form ref="form" :model="form">
                    <div v-for="(itemSum, idxSum) in boxData" :key="idxSum">
                        <el-divider>{{itemSum.txt}}</el-divider>
                        <el-row>
                            <el-col v-for="(item, idx) in itemSum.children" :key="idx" :span="8">
                                <el-form-item v-if="item.type==='select'" :label="item.label" :prop="item.prop"
                                    :rules="item.rules">
                                    <el-select v-model="item.model" :placeholder="item.placeholder" size="medium"
                                        :disabled="item.disabled" clearable>
                                        <el-option v-for="val in item.options" :key="val.code" :label="val.name"
                                            :value="val.code">
                                        </el-option>
                                    </el-select>
                                </el-form-item>
                                <el-form-item v-if="item.type==='input'" :label="item.label" :prop="item.prop"
                                    :rules="item.rules">
                                    <el-input v-model.trim="item.model" size="medium" :placeholder="item.placeholder"
                                        clearable :disabled="item.disabled" clearable></el-input>
                                </el-form-item>
                            </el-col>
                        </el-row>
                    </div>
                </el-form>
                <div style="text-align: right">
                    <el-button class="btnnormal marginR" type="primary" disabled>修改</el-button>
                    <el-button class="btnnormal" type="primary" @click="submitEvent">执行</el-button>
                </div>
            </div>
        </div>
    </div>
</template>
<script>
    import {
        validPercent
    } from '@/validator/validator'
    export default {
        name: 'ALarm',
        data() {
            return {
                form: {
                    
                },
                boxData: [{
                        txt: '盯盘维度',
                        children: [{
                                type: 'select',
                                model: '',
                                prop: 'user_name',
                                label: 'PIN',
                                placeholder: '请选择PIN',
                                options: [{
                                    name: '小米',
                                    code: '小米'
                                }],
                                rules: {
                                    required: true,
                                    validator: validPercent.bind(this, this, 0, 0),
                                    trigger: 'change'
                                },
                                disabled: false
                            },
                            {
                                type: 'input',
                                model: '',
                                prop: 'user_password',
                                label: '密码',
                                placeholder: '请输入密码',
                                rules: {
                                    required: true,
                                    validator: validPercent.bind(this, this, 0, 1),
                                    trigger: 'blur'
                                },
                                disabled: true
                            },
                        ]
                    },
                    {
                        txt: '触发条件',
                        children: [{
                                type: 'select',
                                model: '',
                                prop: 'data',
                                label: '时间',
                                placeholder: '请选择时间',
                                rules: {
                                    required: true,
                                    validator: validPercent.bind(this, this, 1, 0),
                                    trigger: 'change'
                                },
                                options: [],
                                disabled: true
                            },
                        ]
                    },
                    {
                        txt: '执行操作',
                        children: [{
                                type: 'select',
                                model: '1',
                                prop: 'optionType',
                                label: '操作类型',
                                placeholder: '请选择操作类型',
                                rules: {
                                    required: true,
                                    validator: validPercent.bind(this, this, 2, 0),
                                    trigger: 'change'
                                },
                                options: [{
                                    name: '企业微信发送通知',
                                    code: '1'
                                }],
                                disabled: false
                            },
                            {
                                type: 'input',
                                model: '',
                                prop: 'qywx_id',
                                label: '企业微信ID',
                                placeholder: '请输入企业微信ID',
                                rules: {
                                    required: true,
                                    validator: validPercent.bind(this, this, 2, 1),
                                    trigger: 'blur'
                                },
                                disabled: false
                            },

                        ]
                    },
                ]
            }
        },
        methods: {
            submitEvent() {
                const vm = this;
                let data = {}
          // 每个表单绑定的是对应数据中的model,字段名就是prop,这样处理一下要提交的数据
for (let i of vm.boxData) { for (let j of i.children) { vm.$set(data, j.prop, j.model) } } vm.$refs.form.validate((valid) => { if (valid) {               // 执行对应的接口操作 } }) } } } </script>
export const validPercent = (zhi, outerIdx, innerIdx, rule, value, callback) => {
    let iptVale = zhi.boxData[outerIdx].children[innerIdx].model
    let iptPlaceHolder = zhi.boxData[outerIdx].children[innerIdx].placeholder
    if(iptVale) {
        return callback()
    } else {
        return callback(new Error(iptPlaceHolder))
    }
}

 

posted @ 2021-12-08 18:36  行屰  阅读(4258)  评论(1编辑  收藏  举报