【Element】el-form和el-table嵌套实现表格编辑并提交表单校验

目录

一、背景

二、功能实现

2.1、el-form和el-table嵌套说明

2.2、具体代码

三、实际项目应用

3.1、增加添加与删除操作

3.2、添加和删除代码

3.4、实际效果


一、背景

页面需要用到表格采集用户数据,提交时进行表单校验;即表单中嵌套着表格,保存时进行表单校验

二、功能实现

2.1、el-form和el-table嵌套说明

① **:model="formData"**给表单绑定数据,formData是表单的数据对象

② 表单数据对象formData 中定义的tableData是表单内嵌套的表格显示数据

rules为表单绑定的校验规则

④**:prop="'tableData.' + scope.$index + '.name'"** 绑定传入Form 组件的 model 中对应的字段name

⑤ **:rules="rules.name"**绑定表单校验规则

⑥ 整个html结构是一个大表单 el-form里边嵌套的el-table,而el-table中又嵌套了表单项 el-form-item支持编辑。
备注:大多情况下prop会按照惯有思维直接写入字段,而这里是动态绑定的,另外一定要记得每项动态写入rules来进行绑定表单校验

2.2、具体代码

javascript 复制代码
<template>
  <div>
    <el-form
    :model="formData"
    ref="formRef"
    :rules="rules"
    label-width="108px"
    :inline="true"
    >
    <el-table
    :data="formData.tableData"
    style="width: 100%" border
    >
    <el-table-column type="index" width="55" align="center">
    </el-table-column>
    <el-table-column label="姓名" prop="name" resizable align="center" header-align="center">
      <template slot-scope="scope">
        <el-form-item :prop="'tableData.' + scope.$index + '.name'" :rules="rules.name">
          <el-input type="text" size="small" placeholder="请输入姓名" v-model="scope.row.name"></el-input>
        </el-form-item>
      </template>
    </el-table-column>
    <el-table-column label="年龄" prop="age" resizable align="center" header-align="center">
      <template slot-scope="scope">
        <el-form-item :prop="'tableData.' + scope.$index + '.age'" :rules="rules.age">
          <el-input type="text" size="small" placeholder="请输入年龄" v-model="scope.row.age"></el-input>
        </el-form-item>
      </template>
    </el-table-column>
    <el-table-column label="性别" prop="sex" resizable align="center" header-align="center">
      <template slot-scope="scope">
        <el-form-item :prop="'tableData.' + scope.$index + '.sex'" :rules="rules.sex">
          <el-input type="text" size="small" placeholder="请输入性别" v-model="scope.row.sex"></el-input>
        </el-form-item>
      </template>
    </el-table-column>
    </el-table>
    <el-form-item class="footer">
    <el-button type="primary" @click="save">保存</el-button>
    <el-button>取消</el-button>
    </el-form-item>
   </el-form>
  </div>
</template>

<script>
export default{
  data(){
    return{
      formData:{
        tableData:[
          {name:'张三',age:18,sex:''},
          {name:'李四',age:19,sex:''},
        ]
      },
      rules:{
        name:[
        { required: true, message: '请输入姓名', trigger: 'blur' },
        ],
        age:[
        { required: true, message: '请输入年龄', trigger: 'blur' },
        ],
        sex:[
        { required: true, message: '请输入性别', trigger: 'blur' },
        ],
      }
    }
  },
  methods:{
    //保存
    save(){
      this.$refs.formRef.validate((valid) => {
        console.log('valid',valid);
        if(valid){
          //如果valid为true,表示校验通过,可以提交表单,调取接口进行保存
          console.log('表单校验通过');
        }else {
        this.$message.warning("请填写完整的数据");
       }
      })
    },
  }
}
</script>

<style lang="scss" scoped>
.footer{
  margin-top: 50px;
}
</style>

三、实际项目应用

3.1、增加添加与删除操作

**需求:**表格增加操作项,具有添加和删除按钮,第一项无法删除,点击添加时,动态增加表格的行数,点击删除的时候,删除表格的行数据。

3.2、添加和删除代码

结构:直接添加一个表格项

javascript 复制代码
<el-table-column label="操作" resizable align="center" header-align="center">
  <template slot-scope="{$index}">
    <el-button type="primary" icon="el-icon-plus" circle @click="addTable()" v-if="$index == 0"></el-button>
    <el-button icon="el-icon-minus" circle @click="delTable($index)" v-if="$index > 0"></el-button>
  </template>
</el-table-column>
javascript 复制代码
methods:{
   //添加
    addTable(){
      let newArr = [
        {
          name:'',
          age:'',
          sex:''
        }
      ]
      this.formData.tableData.push(...newArr)
    },
    //删除
    delTable(i){
      this.formData.tableData.splice(i,1)
    }
}

3.3、完整代码

javascript 复制代码
<template>
  <div>
    <el-form
    :model="formData"
    ref="formRef"
    :rules="rules"
    label-width="108px"
    :inline="true"
    >
    <el-table
    :data="formData.tableData"
    style="width: 100%" border
    >
    <el-table-column type="index" width="55" align="center">
    </el-table-column>
    <el-table-column label="姓名" prop="name" resizable align="center" header-align="center">
      <template slot-scope="scope">
        <el-form-item :prop="'tableData.' + scope.$index + '.name'" :rules="rules.name">
          <el-input type="text" size="small" placeholder="请输入姓名" v-model="scope.row.name"></el-input>
        </el-form-item>
      </template>
    </el-table-column>
    <el-table-column label="年龄" prop="age" resizable align="center" header-align="center">
      <template slot-scope="scope">
        <el-form-item :prop="'tableData.' + scope.$index + '.age'" :rules="rules.age">
          <el-input type="text" size="small" placeholder="请输入年龄" v-model="scope.row.age"></el-input>
        </el-form-item>
      </template>
    </el-table-column>
    <el-table-column label="性别" prop="sex" resizable align="center" header-align="center">
      <template slot-scope="scope">
        <el-form-item :prop="'tableData.' + scope.$index + '.sex'" :rules="rules.sex">
          <el-input type="text" size="small" placeholder="请输入性别" v-model="scope.row.sex"></el-input>
        </el-form-item>
      </template>
    </el-table-column>
    <el-table-column label="操作" resizable align="center" header-align="center">
     <template slot-scope="{$index}">
      <el-button type="primary" icon="el-icon-plus" circle @click="addTable()" v-if="$index == 0"></el-button>
      <el-button icon="el-icon-minus" circle @click="delTable($index)" v-if="$index > 0"></el-button>
      </template>
     </el-table-column>
    </el-table>
    <el-form-item class="footer">
    <el-button type="primary" @click="save">保存</el-button>
    <el-button>取消</el-button>
    </el-form-item>
   </el-form>
  </div>
</template>

<script>
export default{
  data(){
    return{
      formData:{
        tableData:[
          {name:'张三',age:18,sex:'男'},
          {name:'李四',age:19,sex:''},
        ]
      },
      rules:{
        name:[
        { required: true, message: '请输入姓名', trigger: 'blur' },
        ],
        age:[
        { required: true, message: '请输入年龄', trigger: 'blur' },
        ],
        sex:[
        { required: true, message: '请输入性别', trigger: 'blur' },
        ],
      }
    }
  },
  methods:{
    //保存
    save(){
      this.$refs.formRef.validate((valid) => {
        console.log('valid',valid);
        if(valid){
          //如果valid为true,表示校验通过,可以提交表单,调取接口进行保存
          console.log('表单校验通过');
        }else {
        this.$message.warning("请填写完整的数据");
       }
      })
    },
    //添加
    addTable(){
      let newArr = [
        {
          name:'',
          age:'',
          sex:''
        }
      ]
      this.formData.tableData.push(...newArr)
    },
    //删除
    delTable(i){
      this.formData.tableData.splice(i,1)
    }
  }
}
</script>

<style>
.footer{
  margin-top: 50px;
}
</style>

3.4、实际效果

**最后:**👏👏 😀😀😀 👍👍

相关推荐
Мартин.几秒前
[Meachines] [Easy] Sea WonderCMS-XSS-RCE+System Monitor 命令注入
前端·xss
一 乐1 小时前
学籍管理平台|在线学籍管理平台系统|基于Springboot+VUE的在线学籍管理平台系统设计与实现(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·学习
昨天;明天。今天。1 小时前
案例-表白墙简单实现
前端·javascript·css
数云界1 小时前
如何在 DAX 中计算多个周期的移动平均线
java·服务器·前端
风清扬_jd1 小时前
Chromium 如何定义一个chrome.settingsPrivate接口给前端调用c++
前端·c++·chrome
安冬的码畜日常1 小时前
【玩转 JS 函数式编程_006】2.2 小试牛刀:用函数式编程(FP)实现事件只触发一次
开发语言·前端·javascript·函数式编程·tdd·fp·jasmine
ChinaDragonDreamer2 小时前
Vite:为什么选 Vite
前端
小御姐@stella2 小时前
Vue 之组件插槽Slot用法(组件间通信一种方式)
前端·javascript·vue.js
GISer_Jing2 小时前
【React】增量传输与渲染
前端·javascript·面试
GISer_Jing2 小时前
WebGL在低配置电脑的应用
javascript