最近在作后台管理页面,由于对样式没有特别多的要求,最终选择了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>复制代码
至此两个问题所有解决了,其实都不是什么大的问题,涉及到的东西也都很简单,无非仍是使用得少不熟悉而已,本文也就简单记录下问题及相关解决办法,给本身和有相关问题的同鞋提供一个解决思路。