Vue elementUI表单嵌套表格并对每行进行校验详解

2022-04-15 0 556
目录
  • 效果展示
  • 代码链接
  • 关键代码
    • 表格数据
    • 组件嵌套
    • 校验方法
    • 重置方法
  • 完整代码
    • 总结

      效果展示

      先看看这是不是需要的效果^_^

      Vue elementUI表单嵌套表格并对每行进行校验详解

      如图,ElementUI 表单里嵌套了表格,表格内每行能进行【保存】【新增】【编辑】【删除】【重置】等操作,同时可以对每行的某些字段进行校验(而不是整个表单校验!),这种需求很常见,所以记录下来。

      代码链接

      gitee地址

      关键代码

      表格数据

      // 数据格式必须是【对象嵌套数组】,【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 }
        ]
      },
      

      组件嵌套

      1. 添加字段校验的时候,格式必须写成这样的 :prop=”‘list.’ + scope.$index + ‘.name'”
        这是 elementui 规定的格式,渲染后的结果为 list.1.name
      2. 每个字段要动态绑定表单的 rules 属性
      3. 如果不是以上的格式,会出错!!!
      // 表单必须嵌套在表格的外面,表单必须绑定【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>
      

      校验方法

      1. 表单的字段对象存在于 this.$refs[‘form’].fields 中,并且字段对象具有 prop【datas.1.name】 属性和 validateField 方法【验证 datas.1.name 能否通过校验】
      2. 但是 validateField 方法需要手动创建来验证能否通过校验
      3. 必须创建,否则会出错!!!
      // 表单校验方法
      // 【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"  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>

      总结

      到此这篇关于Vue elementUI表单嵌套表格并对每行进行校验的文章就介绍到这了,更多相关elementUI表单嵌套表格内容请搜索NICE源码以前的文章或继续浏览下面的相关文章希望大家以后多多支持NICE源码!

      免责声明:
      1、本网站所有发布的源码、软件和资料均为收集各大资源网站整理而来;仅限用于学习和研究目的,您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。 不得使用于非法商业用途,不得违反国家法律。否则后果自负!

      2、本站信息来自网络,版权争议与本站无关。一切关于该资源商业行为与www.niceym.com无关。
      如果您喜欢该程序,请支持正版源码、软件,购买注册,得到更好的正版服务。
      如有侵犯你版权的,请邮件与我们联系处理(邮箱:skknet@qq.com),本站将立即改正。

      NICE源码网 JavaScript Vue elementUI表单嵌套表格并对每行进行校验详解 https://www.niceym.com/22379.html