单页面内循环遍历的多个表单做校验(ui框架:elementui + uview)
element
A Vue.js 2.0 UI Toolkit for Web
项目地址:https://gitcode.com/gh_mirrors/eleme/element
免费下载资源
·
业务需求描述
界面展示:
用户每次在【物资扫码】成功后,都会在右侧【物资列表】中增加一个如图的结构(分为上中下三部分,上为【物资编号】,中为表格展示的物资基本信息,下为用户需要填写的表单项【本次组盘数】),需要在用户点击【保存】时,校验每一个表单项必填且数量大于1。
所用技术描述
客户要求该界面支持双端(网页端 + 移动设备端)
网页端采用:vue+elementui
移动设备端采用:uniapp+uview
网页端(vue+elementui)实现方式及具体代码
界面左侧就是简单的点击事件不做赘述,重点讲右侧的表单校验。
<el-col :span="18">
<div class="main_div">
<div class="table_item" v-for="(item,index) in tableData" :key="index">
<div class="materials_div">
<div class="materials_code">{{index + 1}} | 批次号:{{item.batchNum}}</div>
</div>
<div class="table_div">
<div style="width:91%">
<!-- el-table组件接收一个数组,而tableData是一个对象数组,所以此处将遍历得到得对象转变为一个数组赋值给组件 -->
<!-- 此处可以写[tableData[index]] 也可以写 [item],效果是一样的 -->
<el-table
v-loading="loading"
:data="[tableData[index]]"
border
highlight-current-row
>
<el-table-column label="物资类别" align="center" prop="materialsTypeName" />
<el-table-column label="物资名称" align="center" prop="materialsName" />
<el-table-column label="规格" align="center" prop="specs" />
<el-table-column label="数量" align="center" prop="repertoryNum" />
<el-table-column label="待组盘数量" align="center" prop="discNum" />
<el-table-column label="所属仓库" align="center" prop="storeId" :formatter="storeIdFormat" />
<el-table-column label="所属库区" align="center" prop="reserveId" :formatter="reserveIdFormat" />
<el-table-column label="备注" align="center" prop="remark" />
</el-table>
</div>
<div class="delte_btn" @click="deleteHandle(item,index)">删除</div>
</div>
<!-- el-form表单接收一个数组,即遍历得到的tableData[index] -->
<!-- 表单校验规则比较简单,我选择了写在行内的形式 -->
<el-form class="form" ref="materialsManageForm" :model="tableData[index]">
<el-form-item label="本次组盘数" prop="thisNum"
:rules="{
required: true, message: '本次组盘数不能为空', trigger: 'blur'
}"
>
<el-input-number
v-model="tableData[index].thisNum"
:min="1"
>
</el-input-number>
</el-form-item>
</el-form>
</div>
</div>
<div class="save_btn" @click="submitForm">保存</div>
</el-col>
export default {
data() {
return {
// 组盘数据,是一个对象数组,数据通过用户扫码得到的编号访问后台得到,大致就是=>[{},{}]
tableData:[],
};
},
methods:{
// 保存
submitForm() {
//flag为表单校验是否成功的标志变量
var flag = true;
//当一个页面有多个refs 为 materialsManageForm 的表单时,
//this.$refs["materialsManageForm"]会得到一个数组,于是遍历这个数组,去校验每一个表单是否符合校验规则
this.$refs["materialsManageForm"].forEach(ii=>{
ii.validate((valid) => {
if (valid) {
//校验成功,不对flag做操作
} else {
//一旦有一个表单不符合校验规则,将flag设置为false
flag = false;
console.log('error submit!!');
return false;
}
});
})
if(flag){
//校验成功,访问后台做保存数据等操作
}else{
//校验失败,此时界面上已经会有elemnt自带的提示
//可不做操作,也可提示用户,也可做后续操作
}
}
}
}
移动端(uniapp+uview)实现方式及具体代码
同样只讲右侧的表单校验。
<view class="right_view">
<view class="main_div">
<view class="table_item" v-for="(item,index) in tableData" :key="index">
<view class="materials_div">
<view class="materials_code">{{index + 1}} | 物资编号:{{item.materialsCode}}</view>
</view>
<view class="table_div">
<view style="width:91%">
<!-- 此处的表格并非uview中自带的组件,需要从uniapp插件市场导入项目 -->
<!-- uniapp官网相关介绍 => https://uniapp.dcloud.net.cn/component/uniui/uni-table.html#%E4%BB%8B%E7%BB%8D -->
<!-- uni-table组件地址 => https://ext.dcloud.net.cn/plugin?name=uni-table -->
<uni-table border stripe emptyText="暂无更多数据">
<!-- 表头行 -->
<uni-tr>
<uni-th align="center">物资类别</uni-th>
<uni-th align="center">物资名称</uni-th>
<uni-th align="center">规格</uni-th>
<uni-th align="center">数量</uni-th>
<uni-th align="center">待组盘数量</uni-th>
<uni-th align="center">所属仓库</uni-th>
<uni-th align="center">所属库区</uni-th>
<uni-th align="center">备注</uni-th>
</uni-tr>
<!-- 表格数据行 -->
<uni-tr v-for="(ite, ind) in [item]" :key="ind">
<uni-td align="center">{{ite.materialsTypeName}}</uni-td>
<uni-td align="center">{{ite.materialsName}}</uni-td>
<uni-td align="center">{{ite.specs}}</uni-td>
<uni-td align="center">{{ite.repertoryNum}}</uni-td>
<uni-td align="center">{{ite.discNum}}</uni-td>
<uni-td align="center">{{storeIdFormat(ite)}}</uni-td>
<uni-td align="center">{{reserveIdFormat(ite)}}</uni-td>
<uni-td align="center">{{ite.remark}}</uni-td>
</uni-tr>
</uni-table>
</view>
<view class="delte_btn" @click="deleteHandle(item,index)">删除</view>
</view>
<u--form errorType="toast" ref="materialsManageForm" :model="tableData[index]"
labelWidth="auto">
<u-form-item label="本次组盘数" prop="thisNum">
<u-number-box v-model="tableData[index].thisNum" integer :min="1"
></u-number-box>
</u-form-item>
</u--form>
</view>
</view>
<view class="save_btn" @click="submitForm">保存</view>
</view>
export default {
data() {
return {
// 组盘数据,是一个对象数组,数据通过用户扫码得到的编号访问后台得到,大致就是=>[{},{}]
tableData:[],
//表单项校验是否成功的标志属性,因为uview用了promise方式进行校验,所以此处得把formFlag定义在这里
formFlag:true
};
},
methods:{
//此处为用户扫码后向右侧新增一个物料的方法,uniapp和element不同,uniapp需要手动给表单添加校验规则,故此把这个方法写出来,
//访问后台过程有所简略,重点是向tableData push一个新的对象时,对象中必须有要校验的表单项属性,
//该例子中为【thisNum】。如果没有该属性,控制台会报错
newRow() {
var _this = this;
this.tableData.push({
thisNum: 0
});
//给materialsManageForm添加规则时,节点必须已经挂载完毕,所以用了setTimeout。目前没想到更好的办法,等以后想到了再回来补充
setTimeout(() => {
_this.$refs["materialsManageForm"].forEach(ii => {
ii.setRules(_this.formRules)
})
}, 1000)
},
//uview采用了promise方式对表单进行校验,所以就不能再使用简单的forEach,因为我们需要等待所有的表单都校验完毕,再去获取flag
//此处为达到这个效果,用了new Promise的办法
checkFormValid() {
this.formFlag = true;
return new Promise((resolve, reject) => {
let list = [];
this.$refs["materialsManageForm"].forEach(ii => {
const p = new Promise((reso, rej) => {
ii.validate().then(res => {
// 校验通过,this.formFlag值不变
}).catch(errors => {
// 有校验不通过的,this.formFlag值为false
this.formFlag = false;
}).finally(() => {
reso(); //单个接口执行完毕
})
})
list.push(p)
})
Promise.all(list).then(result => {
resolve() //所有接口都执行完毕
})
})
},
// 保存
submitForm() {
var _this = this;
this.checkFormValid().then(res => {
if (_this.formFlag) {
//表单校验成功,访问后台做保存数据等操作
}
})
},
}
}
以上就是两种框架校验的具体过程了,此博文重点在分享完成需求的方法和思路,所以如果因为省略了很多中间代码,在复制过程中有所遗漏导致代码不能粘贴即用,还望读者见谅。
GitHub 加速计划 / eleme / element
54.06 K
14.63 K
下载
A Vue.js 2.0 UI Toolkit for Web
最近提交(Master分支:3 个月前 )
c345bb45
7 个月前
a07f3a59
* Update transition.md
* Update table.md
* Update transition.md
* Update table.md
* Update transition.md
* Update table.md
* Update table.md
* Update transition.md
* Update popover.md 7 个月前
更多推荐
已为社区贡献1条内容
所有评论(0)