目录
效果展示
先看看这是不是需要的效果^_^
如图,ElementUI 表单里嵌套了表格,表格内每行能进行【保存】【新增】【编辑】【删除】【重置】等操作,同时可以对每行的某些字段进行校验(而不是整个表单校验!),这种需求很常见,所以记录下来。
代码链接
关键代码
表格数据
// 数据格式必须是【对象嵌套数组】,【form】绑定表单,【list】绑定表格 form: { // 表格数据 list: [ { id: 1, name: \'小叶\', age: \'12\', phone: \'123456\', show: true }, { id: 2, name: \'小李\', age: \'23\', phone: \'123457\', show: true }, { id: 3, name: \'小林\', age: \'12\', phone: \'123458\', show: true } ] },
组件嵌套
- 添加字段校验的时候,格式必须写成这样的 :prop="'list.' + scope.$index + '.name'"
这是 elementui 规定的格式,渲染后的结果为 list.1.name - 每个字段要动态绑定表单的 rules 属性
- 如果不是以上的格式,会出错!!!
// 表单必须嵌套在表格的外面,表单必须绑定【rules】【ref】属性 <el-form :model=\"form\" :rules=\"rules\" ref=\"form\"> <el-table :data=\"form.list\"> <el-table-column prop=\"name\" label=\"姓名\"> <template scope=\"scope\"> // 每个字段动态的绑定表单的【prop】【rules】属性 <el-form-item :prop=\"\'list.\' + scope.$index + \'.name\'\" :rules=\"rules.name\"> <el-input size=\"mini\" v-model=\"scope.row.name\" placeholder=\"请输入\" clearable></el-input> </el-form-item> </template> </el-table-column> </el-table> </el-form>
校验方法
- 表单的字段对象存在于 this.$refs['form'].fields 中,并且字段对象具有 prop【datas.1.name】 属性和 validateField 方法【验证 datas.1.name 能否通过校验】
- 但是 validateField 方法需要手动创建来验证能否通过校验
- 必须创建,否则会出错!!!
// 表单校验方法 // 【form】是需要校验的表单,就是表单中【ref】绑定的字段 // 【index】是需要传入的行数,字段【scope.$index】 validateField(form, index) { let result = true; for (let item of this.$refs[form].fields) { if(item.prop.split(\".\")[1] == index){ this.$refs[form].validateField(item.prop, err => { if(err !=\"\") { result = false; } }); } if(!result) break; } return result; }
重置方法
// 对【需要校验】的表单字段进行重置 // 参数同校验方法,如果是全部重置 reset(form, index) { this.$refs[form].fields.forEach(item => { if(item.prop.split(\".\")[1] == index){ item.resetField(); } }) } // 如果需要全部重置可以直接质控表单中字段 // 【row】是每行传入的数据 resetRow(row) { row.name = \"\"; row.age = \"\"; row.phone = \"\"; }
完整代码
因为用的是在线链接,网络不稳定时页面不一定能加载出来,使用时可以更换成本地的!
<!DOCTYPE html> <html lang=\"zh\"> <head> <meta charset=\"UTF-8\"> <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"> <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"> <title>vue表单嵌套表格逐行验证</title> <script src=\"https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js\"></script> <!-- 引入样式 --> <link rel=\"stylesheet\" href=\"https://unpkg.com/element-ui/lib/theme-chalk/index.css\" rel=\"external nofollow\" > <!-- 引入组件库 --> <script src=\"https://unpkg.com/element-ui/lib/index.js\"></script> </head> <body> <div id=\"app\"> <!-- 页面组件 --> <h2 style=\"text-align: center; line-height: 23px;color: #909399;\">vue表单嵌套表格逐行验证</h2> <el-form :model=\"form\" :rules=\"rules\" ref=\"form\" :inline=\"true\" style=\"margin: 23px auto 0px; width: 96%; overflow: hidden;\"> <el-table border :data=\"form.list\"> <el-table-column align=\"center\" prop=\"id\" label=\"序号\" width=\"55\"> </el-table-column> <el-table-column align=\"center\" prop=\"name\" label=\"姓名\"> <template scope=\"scope\"> <el-form-item :prop=\"\'list.\' + scope.$index + \'.name\'\" :rules=\"rules.name\" v-if=\"scope.row.show\"> <el-input size=\"mini\" v-model=\"scope.row.name\" placeholder=\"请输入\" clearable> </el-input> </el-form-item> <div v-if=\"!scope.row.show\">{{scope.row.name}}</div> </template> </el-table-column> <el-table-column align=\"center\" prop=\"age\" label=\"年龄\"> <template scope=\"scope\"> <el-form-item :prop=\"\'list.\' + scope.$index + \'.age\'\" :rules=\"rules.age\" v-if=\"scope.row.show\"> <el-input size=\"mini\" v-model=\"scope.row.age\" placeholder=\"请输入\" clearable> </el-input> </el-form-item> <div v-if=\"!scope.row.show\">{{scope.row.age}}</div> </template> </el-table-column> <el-table-column align=\"center\" prop=\"phone\" label=\"联系方式\"> <template scope=\"scope\"> <el-form-item :prop=\"\'list.\' + scope.$index + \'.phone\'\" :rules=\"rules.phone\" v-if=\"scope.row.show\"> <!-- <el-form-item v-if=\"scope.row.show\"> --> <el-input size=\"mini\" v-model=\"scope.row.phone\" placeholder=\"请输入\" clearable> </el-input> </el-form-item> <div v-if=\"!scope.row.show\">{{scope.row.phone}}</div> </template> </el-table-column> <el-table-column label=\"操作\" align=\"center\" width=\"290\" fixed=\"right\"> <template slot-scope=\"scope\"> <el-button type=\"text\" style=\"color: #E6A23C;\" @click=\"save(scope.$index, scope.row)\" v-if=\"scope.row.show\" icon=\"el-icon-check\">保存 </el-button> <el-button type=\"text\" style=\"color: #409EFF;\" @click=\"edit(scope.row)\" v-if=\"!scope.row.show\" icon=\"el-icon-edit\">编辑 </el-button> <el-button type=\"text\" style=\"color: #67C23A;\" v-if=\"scope.$index+1 == listLength\" @click=\"addRow(scope.$index, scope.row)\" icon=\"el-icon-plus\">新增 </el-button> <el-button type=\"text\" style=\"color: #F56C6C;\" @click=\"delRow(scope.$index, scope.row)\" icon=\"el-icon-delete\">删除 </el-button> <el-button type=\"text\" style=\"color: #909399;\" @click=\"reset(\'form\', scope.$index)\" v-if=\"scope.row.show\" icon=\"el-icon-refresh\">重置 </el-button> <!-- <el-button type=\"text\" style=\"color: #909399;\" @click=\"resetRow(scope.row)\" v-if=\"scope.row.show\" icon=\"el-icon-refresh\">重置 </el-button> --> </template> </el-table-column> </el-table> </el-form> </div> </body> </html> <script> var app = new Vue({ el: \'#app\', data() { return { // 表单数据 form: { // 表格数据 list: [{ id: 1, name: \'\', age: \'\', phone: \'\', show: true }] }, // 表单验证规则 rules: { name: [{ required: true, message: \'请输入姓名!\', trigger: \'blur\' }], age: [{ required: true, message: \'请输入年龄!\', trigger: \'blur\' }], phone: [{ required: true, message: \'请输入联系方式!\', trigger: \'blur\' }], }, // 表格长度默认为 1 listLength: 1, } }, methods: { // 校验 validateField(form, index) { let result = true; for (let item of this.$refs[form].fields) { if (item.prop.split(\".\")[1] == index) { this.$refs[form].validateField(item.prop, err => { if (err != \"\") { result = false; } }); } if (!result) break; } return result; }, // 重置【只针对校验字段】 reset(form, index) { this.$refs[form].fields.forEach(item => { if (item.prop.split(\".\")[1] == index) { item.resetField(); } }) }, // 重置【全部】 resetRow(row) { row.name = \"\"; row.age = \"\"; row.phone = \"\"; }, // 保存 save(index, row) { if (!this.validateField(\'form\', index)) return; row.show = false; }, // 新增 addRow(index, row) { if (!this.validateField(\'form\', index)) return; this.form.list.push({ id: index + 2, name: \'\', age: \'\', phone: \'\', show: true }); this.listLength = this.form.list.length; }, // 编辑 edit(row) { row.show = true; }, // 删除 delRow(index, row) { if (this.form.list.length > 1) { this.form.list.splice(index, 1); this.listLength = this.form.list.length; } else { this.form.list = [{ id: 1, name: \'\', age: \'\', phone: \'\', show: true }]; } }, } }) </script>
总结
© 版权声明
THE END
暂无评论内容