1. 程式人生 > 其它 >【elementUi】關於el-form使用自定義校驗規則的傳參問題

【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))
    }
}