vue elementUI表單驗證問題之數組嵌套和select的change事件傳值問題

最近在作後臺管理頁面,由於對樣式沒有特別多的要求,最終選擇了element-ui組件庫結合vue技術棧方法進行開發,頁面功能相對統一,主要功能點是表單的驗證,前期已經有大佬對element表單驗證進行了封裝,開發只要拿來直接調用就行了,可是期間也遇到了一些小問題,在此簡單記錄下。vue

因爲涉及到公司內部東西,原型圖就不上了,先來一段簡單的代碼拋出問題element-ui

//======template
<el-dialog @close="cancelDialog" :visible.sync="dialogIsShow">
    <el-form  ref="createDiaForm"  :model="resNewData"  :rules="resFormRule">
        <el-form-item label="規則名稱" prop="name">
            <el-input placeholder="請輸入規則名稱" v-model="resNewData.name"></el-input>
        </el-form-item>
        <h3 class="createDiaTitle otherType">
           <span>其餘屬性</span>
           <el-button type="primary" size="small">+添加屬性</el-button>
        </h3>
        <div class="addRule" v-for="(item, idx) in resNewData.attributeVoList" :key="idx">
            <div class="addRuleForm">
                <el-form-item  class="addInline"  label="屬性名稱">
                   <el-select placeholder="請選擇" v-model="item.name">
                       <el-option  v-for="item in newAddTypeName"  :key="item.name"  :label="item.name"  :value="item.value" ></el-option>
                   </el-select>
                </el-form-item>
                <el-form-item  class="addInline"  label="排序位">
                    <el-input placeholder="請輸入排序位" v-model.number="item.position"></el-input> 
                </el-form-item>
            </div>
        </div>
    </el-form>
</el-dialog>

//js
data(){
    return {
        resNewData: {
           name: "", 
           attributeVoList: [
               { name: "", position: ""}
           ]
         },
         newAddTypeName: [            {name: '選擇一', value: '111', position: '1'},               {name: '選擇二', value: '222', position: '2'},         ],         resFormRule: {
             name: [{ required: true, message: "請輸入規則名稱", trigger: "blur" }]
         }
    }
}
複製代碼

簡單說下結構,一個表單上下兩部分,上半部分一些基礎屬性,下半部分其餘屬性,能夠經過添加按鈕添加更多其餘屬性,同時在選擇其餘屬性的屬性名稱的時候,會在排序位裏自動獲取到對應的排序位。基本的佈局和邏輯已經都有了,在進行表單驗證的時候,發現基礎屬性是能夠準確驗證的,開始對下半部分(下面統稱「其餘屬性」)添加校驗邏輯。數組

問題一:循環嵌套數據表單驗證

開始考慮的是和基礎屬性方法同樣,經過給「el-form-item」添加一個對應的prop=「對應的字段值」進行校驗,結果發現根本行不通,嘗試了各類prop都沒有獲得想要的結果,只能去看下各位前輩是如何填坑的了。bash

經過查詢,找到了解決問題的辦法(附上原文連接:vue elementUI表單校驗功能值數組多層嵌套),第一個是給其餘屬性添加一個新的from表單,model值對應當前循環的子對象;第二個方法是動態綁定循環下的各個prop名稱。佈局

方法一:ui

//爲了直觀,只放出循環部分代碼

<el-form :model='item' v-for="(item, idx) in resNewData.attributeVoList" :key="idx">           
    <el-form-item  class="addInline"  label="屬性名稱" prop="name" 
        :rule=「[{require: true, message: '請選擇名稱', trigger: 'change'}]」>        <el-select placeholder="請選擇" v-model="item.name">
            <el-option  v-for="item in newAddTypeName"  :key="item.name"  :label="item.name"  :value="item.value" ></el-option>
        </el-select>
    </el-form-item>
    <el-form-item  class="addInline"  label="排序位" prop="position">
        <el-input placeholder="請輸入排序位" v-model.number="item.position"></el-input>
    </el-form-item>
</el-form>複製代碼

此方法結構也很簡單,就是把其餘屬性新添加了個表單,表單裏的方法和常規寫法一致,這個方法我嘗試了,對於我項目裏表驗證依舊是有問題的,多是表單嵌套問題致使的,可是常規的循環驗證此方法是能夠的。所以我才用了第二種方法。this


方法二:spa

//爲了直觀,只放出循環部分代碼

<div  v-for="(item, idx) in resNewData.attributeVoList" :key="idx">           
    <el-form-item  class="addInline"  label="屬性名稱" :prop="`attributeVoList[${idx}].name`" 
        :rule=「[{require: true, message: '請選擇名稱', trigger: 'change'}]」>
        <el-select placeholder="請選擇" v-model="item.name">
            <el-option  v-for="item in newAddTypeName"  :key="item.name"  :label="item.name"  :value="item.value" ></el-option>
        </el-select>
    </el-form-item>
    <el-form-item  class="addInline"  label="排序位" :prop="`attributeVoList[${idx}].position`">
        <el-input placeholder="請輸入排序位" v-model.number="item.position"></el-input>
    </el-form-item>
</div>複製代碼

方法二,全部的表單數據都在一個表單中,用統一方法進行驗證,完美經過;其實主要也是利用了動態獲取嵌套表單某個item的某個值的方法,和方法一的model=’item‘道理是很類似的。.net

解決了問題一,接下來是另外一個問題,就是下拉框選擇的時候會根據不一樣的選擇自動填充position的值,其實也很簡單,觸發select的change事件就行了。code

問題二:element select的change傳參

經過查詢文檔發現,element的select change事件默認接受一個參數,即當前選中的值。可是根據需求咱們的其餘屬性可能會有多個數據,咱們還須要另外一個參數,即當前選中的是第幾個,而後根據下標去給給不一樣租的position賦值,可是文檔說只接受一個參數,怎麼傳參是個問題~

其實在調用change事件時,是會默認傳一個event對象的,它會包含全部當前選中的值對應的屬性,天然也就能夠取到當前的index,寫法是: change($event, other)

//selectchange事件
changeTypeName(val, idx) { 
    const addTypeName = this.newAddTypeName  
    addTypeName.map(item => {    
        if (item.name == val) {
            this.resNewData.attributeVoList[idx].position = item.position      
        }
    })
}

//給select添加事件
<el-form-item  class="addInline"  label="屬性名稱" :prop="`attributeVoList[${idx}].name`" 
        :rule=「[{require: true, message: '請選擇名稱', trigger: 'change'}]」>
        <el-select placeholder="請選擇" v-model="item.name" @change="changeTypeName($event, idx)">            <el-option  v-for="item in newAddTypeName"  :key="item.name"  :label="item.name"  :value="item.value" ></el-option>
        </el-select>
    </el-form-item>複製代碼

至此兩個問題所有解決了,其實都不是什麼大的問題,涉及到的東西也都很簡單,無非仍是使用得少不熟悉而已,本文也就簡單記錄下問題及相關解決辦法,給本身和有相關問題的同鞋提供一個解決思路。

相關文章
相關標籤/搜索