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

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

相关推荐
崔庆才丨静觅3 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅4 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅4 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment4 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅5 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊5 小时前
jwt介绍
前端
爱敲代码的小鱼5 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax
吹牛不交税5 小时前
admin.net-v2 框架使用笔记-netcore8.0/10.0版
vue.js·.netcore
Cobyte5 小时前
AI全栈实战:使用 Python+LangChain+Vue3 构建一个 LLM 聊天应用
前端·后端·aigc
NEXT065 小时前
前端算法:从 O(n²) 到 O(n),列表转树的极致优化
前端·数据结构·算法