Vue + ElementUI 实现可编辑表格及校验

效果

动画

完整代码见文末

实现思路

  1. 使用两个表单分别用于实现修改和新增处理。

  2. 通过一个editIndex变量判断是否是编辑状态来决定是否展示输入框,当点击指定行的修改后进行设置即可:

    <el-table-column
      v-for="(column, index) in columns"
      :key="index"
      :label="column.label"
      :prop="column.prop"
      align="center">
      <template #default="{ row, $index }">
        <div v-if="$index === editIndex" class="validate-info">
          <el-form-item :prop="column.prop">
            <el-input v-model="editRow[column.prop]"/>
          </el-form-item>
        </div>
        <span v-else>
          <span>{{ row[column.prop] }}</span>
        </span>
      </template>
    </el-table-column>
    
    edit(row, index) {
      if (this.editIndex > -1) {
        this.$message.warning('请先完成修改中的行')
        return
      }
      this.editRow = {...row}
      this.editIndex = index
    }
    
  3. 通过隐藏表头实现新增表格和修改表格的合并,同时表格数据只有addRow

    <el-table :data="[addRow]" :show-header="false">
        ...
    </el-table>
    

实现细节讲解

  1. 当无数据时只展示新增行:

    image-20230801162740429

    通过设置以下样式即可:

    /deep/ .el-table__empty-block {
    	display: none;
    }
    
  2. 新增或者修改数据行时增加行高用于显示校验信息:

    动画

    行高通过以下样式进行控制,不处于新增或者修改状态时设置为 0 即可:

    .add-table /deep/ .el-form-item {
      margin: 18px 0;
    }
    

    为了在修改时只设置修改行的行高,只需要只对输入框绑定样式即可:

    <div v-if="$index === editIndex" class="validate-info">
      <el-form-item :prop="column.prop">
        <el-input v-model="editRow[column.prop]"/>
      </el-form-item>
    </div>
    

完整代码

<template>
  <div class="app">
    <el-form
      ref="editableForm"
      :model="editRow"
      :rules="rules"
      label-width="0"
      :show-message="true"
      class="editable-table">
      <el-table :data="tableData">
        <el-table-column
          v-for="(column, index) in columns"
          :key="index"
          :label="column.label"
          :prop="column.prop"
          align="center">
          <template #default="{ row, $index }">
            <div v-if="$index === editIndex" class="validate-info">
              <el-form-item :prop="column.prop">
                <el-input v-model="editRow[column.prop]"/>
              </el-form-item>
            </div>
            <span v-else>
              <span>{{ row[column.prop] }}</span>
            </span>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="200" align="center">
          <template #default="{ row, $index }">
            <el-form-item>
              <template v-if="$index === editIndex">
                <el-button type="success" size="mini" plain @click="save">保存</el-button>
                <el-button type="info" size="mini" plain @click="cancel">取消</el-button>
              </template>
              <template v-else>
                <el-button
                  type="primary"
                  size="mini"
                  plain
                  @click="edit(row, $index)">
                  修改
                </el-button>
                <el-popconfirm
                  title="是否确认删除?"
                  @confirm="deleteRow($index)"
                  style="margin-left: 10px;">
                  <el-button slot="reference" type="danger" size="mini" plain>删除</el-button>
                </el-popconfirm>
              </template>
            </el-form-item>
          </template>
        </el-table-column>
      </el-table>
    </el-form>
    <el-form
      ref="addForm"
      :model="addRow"
      :rules="rules"
      label-width="0"
      :show-message="true"
      class="add-table">
      <el-table :data="[addRow]" :show-header="false">
        <el-table-column
          v-for="(column, index) in columns"
          :key="index"
          :label="column.label"
          :prop="column.prop"
          align="center">
          <template #default="{ row }" class="validate-info">
            <div class="validate-info">
              <el-form-item :prop="column.prop">
                <el-input v-model="addRow[column.prop]"/>
              </el-form-item>
            </div>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="200px" align="center">
          <template #default="{ row }">
            <el-form-item>
              <el-button type="success" size="mini" plain @click="add(row)">新增</el-button>
            </el-form-item>
          </template>
        </el-table-column>
      </el-table>
    </el-form>
  </div>
</template>

<script>
export default {
  data() {
    return {
      // 表格数据
      tableData: [
        {
          username: '张三',
          address: '北京'
        },
        {
          username: '李四',
          address: '上海'
        }
      ],
      //配置列
      columns: [
        {
          label: '用户名',
          prop: 'username'
        },
        {
          label: '地址',
          prop: 'address'
        }
      ],
      // 规则
      rules: {
        username: [{required: true, message: '请输入用户名', trigger: 'blur'}],
        address: [{required: true, message: '请输入地址', trigger: 'blur'}],
      },
      // 当前编辑行下标
      editIndex: -1,
      // 当前编辑行
      editRow: {
        username: '',
        address: ''
      },
      // 新增行
      addRow: {
        username: '',
        address: ''
      }
    }
  },
  methods: {
    save() {
      this.$refs.editableForm.validate((valid) => {
        if (valid) {
          this.tableData.splice(this.editIndex, 1, { ...this.editRow })
          this.editIndex = -1
          this.$message.success('修改成功')
        }
        return valid
      })
    },
    cancel() {
      this.editIndex = -1
    },
    edit(row, index) {
      if (this.editIndex > -1) {
        this.$message.warning('请先完成修改中的行')
        return
      }
      this.editRow = {...row}
      this.editIndex = index
    },
    add(row) {
      if (this.editIndex > -1) {
        this.$message.warning('请先完成修改中的行')
        return
      }
      this.$refs.addForm.validate((valid) => {
        if (valid) {
          this.addRow = {}
          this.tableData.push({ ... row})
          this.$message.success('新增成功')
        }
        return valid
      })
    },
    deleteRow(index) {
      this.tableData.splice(index, 1)
      this.$message.success('删除成功!');
    }
  }
}
</script>

<style scoped lang="less">
.app {
  padding: 20px;
  /deep/ .el-form-item {
    margin-bottom: 0;
  }
}

.validate-info {
  /deep/ .el-form-item {
    margin: 18px 0;
  }
}

.editable-table {
  /deep/ .el-table__empty-block {
    display: none;
  }
}

.editable-table, .add-table {
  width: 60%;
  margin: 0 auto;
}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/60514.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

华为QinQ技术的基本qinq和灵活qinq 2种配置案例

基本qinq配置&#xff1a; 运营商pe设备在收到同一个公司的ce发来的的包&#xff0c;统一打上同样的vlan &#xff0c;如上图&#xff0c;同一个家公司两边统一打上vlan 2&#xff0c;等于在原内网vlan 10或20过来的包再统一打上vlan 2的标签&#xff0c;这样传输就不会和其它…

基于text2vec和faiss开发实现文档查询系统初体验

最近接触到了一些文本向量化的预训练模型&#xff0c;感觉相比较自己去基于gensim去训练词向量来说&#xff0c;使用预训练模型可能是更高效的方式了&#xff0c;正好有一个想法一直在想能够以什么样的形式间接的实现问答&#xff0c;说白了这里的问答跟我们理解的chatGPT类型的…

Spark 3.1.1 遇到的 from_json regexp_replace组合表达式慢问题的解决

背景 目前公司在从spark 2.4.x升级到3.1.1的时候&#xff0c;遇到了一类SQL极慢的情况&#xff0c;该SQL的如下(只列举了关键的)&#xff1a; select device_personas.* from(selectdevice_id, ads_id, from_json(regexp_replace(device_personas, (?<(\\{|,))"devic…

【数据结构】——线性表的相关习题

目录 题型一&#xff08;线性表的存储结构&#xff09;题型二&#xff08;链表的判空&#xff09;题型三&#xff08;单链表的建立&#xff09;题型四&#xff08;顺序表、单链表的插入删除操作&#xff09;题型五&#xff08;双链表的插入删除操作&#xff09;题型六&#xff…

【ARM Coresight 系列文章 2.5 - Coresight 寄存器:PIDR0-PIDR7,CIDR0-CIDR3 介绍】

文章目录 1.1 JEDEC 与 JEP1061.2 PIDR0-PIDR7(peripheral identification registers)1.2 CIDR0-CIDR3(Component Identification Registers) 1.1 JEDEC 与 JEP106 JEDEC和JEP106都是来自美国电子工业联合会&#xff08;JEDEC&#xff0c;Joint Electron Device Engineering C…

SpringBoot单元测试

目录 1.什么是单元测试? 2.单元测试有哪些好处? 3.Spring Boot单元测试使⽤ 单元测试的实现步骤 1. ⽣成单元测试类 2. 添加单元测试代码 2.1 .添加Spring Boot框架测试注解:SpringBootTest 2.2 添加单元测试业务逻辑 简单的断⾔说明 1.什么是单元测试? 单元测试(un…

分页Demo

目录 一、分页对象封装 分页数据对象 分页查询实体类 实体类用到的utils ServiceException StringUtils SqlUtil BaseMapperPlus,> BeanCopyUtils 二、示例 controller service dao 一、分页对象封装 分页数据对象 import cn.hutool.http.HttpStatus; import com.…

Python-flask项目入门

一、flask对于简单搭建一个基于python语言-的web项目非常简单 二、项目目录 示例代码 git路径 三、代码介绍 1、安装pip依赖 通过pip插入数据驱动依赖pip install flask-sqlalchemy 和 pip install pymysql 2.配置数据源 config.py DIALECT mysql DRIVER pymysql USERN…

SQL-每日一题【1164. 指定日期的产品价格】

题目 产品数据表: Products 写一段 SQL来查找在 2019-08-16 时全部产品的价格&#xff0c;假设所有产品在修改前的价格都是 10 。 以 任意顺序 返回结果表。 查询结果格式如下例所示。 示例 1: 解题思路 1.题目要求我们查找在 2019-08-16 时全部产品的价格&#xff0c;假设所…

关于java异常的整理

文章目录 一、异常分类二、throw、throws、try-catch-finally三、CglibAopProxy中对异常的处理4、关于UndeclaredThrowableException 一、异常分类 java异常层级结构 Throwable:所有异常的根接口 Error:严重错误,程序无法处理和恢复 例如VirtualMachineError,OOMError等 Excep…

【图像去噪】基于原始对偶算法优化的TV-L1模型进行图像去噪研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

8.5作业

要求实现AB进程对话 a.A进程先发送一句话给B进程&#xff0c;B进程接收后打印 b.B进程再回复一句话给A进程&#xff0c;A进程接收后打印 c.重复1.2步骤&#xff0c;当收到quit后&#xff0c;要结束AB进程 A进程 #include<stdio.h> #include<string.h> #include&…

【新版系统架构补充】-七层模型

网络功能和分类 计算网络的功能 &#xff1a;数据通信、资源共享、管理集中化、实现分布式处理、负载均衡 网络性能指标&#xff1a;速率、带宽&#xff08;频带宽度或传送线路速率&#xff09;、吞吐量、时延、往返时间、利用率 网络非性能指标&#xff1a;费用、质量、标准化…

【Rust】Rust学习

文档&#xff1a;Rust 程序设计语言 - Rust 程序设计语言 简体中文版 (bootcss.com) 墙裂推荐这个文档 第一章入门 入门指南 - Rust 程序设计语言 简体中文版 第二章猜猜看游戏 猜猜看游戏教程 - Rust 程序设计语言 简体中文版 (bootcss.com) // 导入库 use std::io; use s…

2023.08.01 驱动开发day8

驱动层 #include <linux/init.h> #include <linux/module.h> #include <linux/of.h> #include <linux/of_irq.h> #include <linux/interrupt.h> #include <linux/fs.h> #include <linux/gpio.h> #include <linux/of_gpio.h>#…

NVM保姆级安装配置

nvm安装配置 1、NVM简介2、NVM安装三、NVM使用四、NVM常用命令 1、NVM简介 在项目开发过程中&#xff0c;使用到vue框架技术&#xff0c;需要安装node下载项目依赖&#xff0c;但经常会遇到node版本不匹配而导致无法正常下载&#xff0c;重新安装node却又很麻烦。为解决以上问…

Docker 网络模型使用详解 (1)Dockers网络基础

目录 环境准备 Dockers 网络基础 1.端口映射 查看随机映射端口范围 -p可以指定映射到本地端口 映射指定地址和指定端口 映射指定地址 宿主机端口随机分配 指定传输协议 端口暴露 容器互联 自定义网络 现在把container7加入到demo_net中 在启动一个容器加入到demo_net…

Linux进程(二)

文章目录 进程&#xff08;二&#xff09;Linux的进程状态R &#xff08;running&#xff09;运行态S &#xff08;sleeping&#xff09;阻塞状态D &#xff08;disk sleep&#xff09;深度睡眠T&#xff08;stopped&#xff09;状态X&#xff08;dead&#xff09;状态Z&#x…

数据结构 二叉树(C语言实现)

绪论 雄关漫道真如铁&#xff0c;而今迈步从头越。 本章将开始学习二叉树&#xff08;全文共一万两千字&#xff09;&#xff0c;二叉树相较于前面的数据结构来说难度会有许多的攀升&#xff0c;但只要跟着本篇博客深入的学习也可以基本的掌握基础二叉树。 话不多说安全带系好&…

关于 Ubuntu 长按 shift 无效, 按 Esc 直接进入 grub 改密码的解决方法

本次长按shift没有反应&#xff0c;直接进入了系统界面&#xff0c;所以改用长按Esc键&#xff0c;步骤如下&#xff1a; 1. 长按esc&#xff0c;进入grub>提示 2.输入grub>normal &#xff0c;回车 3.上一步回车后&#xff0c;继续敲击Esc &#xff0c;出现grub界面 …