【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、实际效果

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

相关推荐
码上暴富1 小时前
axios请求的取消
前端·javascript·vue.js
JefferyXZF1 小时前
Next.js 初识:从 React 到全栈开发的第一步(一)
前端·全栈·next.js
一只韩非子2 小时前
AI时代,程序员如何优雅地搞定页面设计?
前端·ai编程
新中地GIS开发老师2 小时前
2025Mapbox零基础入门教程(14)定位功能
前端·javascript·arcgis·gis·mapbox·gis开发·地理信息科学
tager3 小时前
Vue 3 组件开发中的"双脚本"困境
前端·vue.js·代码规范
烛阴3 小时前
Int / Floor
前端·webgl
excel3 小时前
使用 PWA 时,为什么你必须手动添加更新逻辑,否则会报错?
前端
Moment3 小时前
Node.js 这么多后端框架,我到底该用哪个?🫠🫠🫠
前端·后端·node.js
尚学教辅学习资料4 小时前
SpringBoot3.x入门到精通系列: 2.3 Web开发基础
前端·springboot·web开发
han_4 小时前
前端遇到页面卡顿问题,如何排查和解决?
前端·javascript·性能优化