最近在作後臺管理頁面,由於對樣式沒有特別多的要求,最終選擇了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事件默認接受一個參數,即當前選中的值。可是根據需求咱們的其餘屬性可能會有多個數據,咱們還須要另外一個參數,即當前選中的是第幾個,而後根據下標去給給不一樣租的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>複製代碼
至此兩個問題所有解決了,其實都不是什麼大的問題,涉及到的東西也都很簡單,無非仍是使用得少不熟悉而已,本文也就簡單記錄下問題及相關解決辦法,給本身和有相關問題的同鞋提供一個解決思路。