如何在 Vue 中创建一个带有表格和表单的弹窗

news2024/9/22 1:28:12

本文将通过一个具体的示例来介绍如何在 Vue 应用中实现一个带有表格和表单功能的弹窗组件。我们将使用 Element UI 库中的 el-dialog 组件来构建这个弹窗,并结合 el-table 和 el-form 来展示数据并允许用户进行编辑。

效果图:

完整代码最底部,以下拆分解析----------

1. 引入必要的 Element UI 组件
 

2. 创建弹窗结构
接下来定义弹窗的基本结构。这里我们使用 el-dialog 组件,并为其设置一些基本属性如标题、宽度等:

<el-dialog
  class="edit-dialog"
  title="编辑"
  width="80%"
  :center="true"
  ref="dialogRef"
  :visible.sync="dialogVisible"
  @close="resetForm('resetForm')"
  :before-close="beforeClose"
  :close-on-click-modal="false"
  :close-on-press-escape="false">
</el-dialog>

3. 添加表单和表格
在弹窗内部添加一个表单 (el-form) 和表格 (el-table),并通过 v-model 双向绑定数据

<el-form ref="formRef" style="padding: 20px" label-width="100px">
  <el-table
    border
    stripe
    class="table-style"
    max-height="350"
    :data="tableData"
    style="width: 100%; min-height: 200px;">
    <!-- 表格列定义 -->
  </el-table>
</el-form>

4. 定义表格列
为表格定义多个列,包括索引、发票类型选择器、输入框等:

<el-table-column type="index" label="序号" align="center" width="60" show-overflow-tooltip></el-table-column>
<el-table-column prop="invoiceType" label="发票类型" align="center" min-width="280">
  <template slot-scope="scope">
    <el-select
      multiple
      style="width: 100%"
      collapse-tags
      v-model="scope.row.invoiceTypeCode">
      <el-option
        v-for="(item, index) in typeList"
        :key="index"
        :label="item.invoiceTypeName"
        :value="item.invoiceTypeCode">
      </el-option>
    </el-select>
  </template>
</el-table-column>
<el-table-column prop="taxCategory" label="税收分类简称" align="center" min-width="180">
  <template slot-scope="scope">
    <el-input placeholder="请输入税收分类简称" v-model="scope.row.taxCategory" clearable></el-input>
  </template>
</el-table-column>
<el-table-column prop="taxRate" label="税率" align="center" min-width="180">
  <template slot-scope="scope">
    <el-input placeholder="请输入税率" v-model="scope.row.taxRate" clearable></el-input>
  </template>
</el-table-column>
<el-table-column prop="dateRange" label="适用时间" align="center" min-width="280">
  <template slot-scope="scope">
    <el-date-picker
      v-model="scope.row.dateRange"
      type="daterange"
      range-separator="至"
      value-format="yyyy-MM-dd"
      start-placeholder="开始日期"
      end-placeholder="结束日期">
    </el-date-picker>
  </template>
</el-table-column>
<el-table-column label="操作" align="center" width="80" :render-header="renderHeader">
  <template slot-scope="scope">
    <i @click.prevent="deleteRow(scope.$index, scope.row)" class="el-icon-delete"></i>
  </template>
</el-table-column>

5. 添加操作按钮
在弹窗底部添加两个按钮用于关闭和保存:

<div slot="footer">
  <el-button size="medium" @click="closeDialog">取消</el-button>
  <el-button size="medium" type="primary" ref="saveButton" @click="saveData('formRef')">保存</el-button>
</div>

6. 定义相关方法
最后,在 Vue 实例的方法部分定义与弹窗相关的处理逻辑,例如关闭时重置表单、保存数据等:

export default {
  data() {
    return {
      dialogVisible: false,
      tableData: [],
      typeList: [], // 示例数据
      formRef: null,
      dialogRef: null
    };
  },
  methods: {
    resetForm(formName) {
      this.$refs[formName].resetFields();
    },
    beforeClose(done) {
      this.resetForm('formRef');
      done();
    },
    deleteRow(index, row) {
      this.tableData.splice(index, 1);
    },
    closeDialog() {
      this.dialogVisible = false;
      this.resetForm('formRef');
    },
    saveData(formName) {
      this.$refs[formName].validate(valid => {
        if (valid) {
          // 保存数据逻辑
          console.log(this.tableData);
          this.closeDialog();
        }
      });
    },
    renderHeader(h, { column }) {
      return h('span', [
        h('i', { style: 'color: #409EFF' }, '添加行'),
        h('span', '操作')
      ]);
    }
  }
};

完整代码如下:

<template>
  <el-dialog
    title="编辑"
    width="80%"
    :center="true"
    ref="dialogRef"
    :visible.sync="dialogVisible"
    @close="resetForm('formRef')"
    :before-close="beforeClose"
    :close-on-click-modal="false"
    :close-on-press-escape="false">
    <el-form ref="formRef" style="padding: 20px" label-width="100px">
      <el-table
        border
        stripe
        class="custom-table"
        max-height="350"
        :data="tableData"
        style="width: 100%; min-height: 200px;">
        <el-table-column type="index" label="序号" align="center" width="60" show-overflow-tooltip></el-table-column>
        <el-table-column prop="invoiceType" label="发票类型" align="center" min-width="280">
          <template slot-scope="scope">
            <el-select
              multiple
              style="width: 100%"
              collapse-tags
              v-model="scope.row.invoiceTypeCode">
              <el-option
                v-for="item in typeList"
                :key="item.invoiceTypeCode"
                :label="item.invoiceTypeName"
                :value="item.invoiceTypeCode">
              </el-option>
            </el-select>
          </template>
        </el-table-column>
        <el-table-column prop="taxCategory" label="税收分类简称" align="center" min-width="180">
          <template slot-scope="scope">
            <el-input
              placeholder="请输入税收分类简称"
              v-model="scope.row.taxCategory"
              clearable>
            </el-input>
          </template>
        </el-table-column>
        <el-table-column prop="taxRate" label="税率" align="center" min-width="180">
          <template slot-scope="scope">
            <el-input
              placeholder="请输入税率"
              v-model="scope.row.taxRate"
              clearable>
            </el-input>
          </template>
        </el-table-column>
        <el-table-column prop="dateRange" label="适用时间" align="center" min-width="280">
          <template slot-scope="scope">
            <el-date-picker
              v-model="scope.row.dateRange"
              type="daterange"
              range-separator="至"
              value-format="yyyy-MM-dd"
              start-placeholder="开始日期"
              end-placeholder="结束日期">
            </el-date-picker>
          </template>
        </el-table-column>
        <el-table-column label="操作" align="center" width="80" :render-header="renderHeader">
          <template slot-scope="scope">
            <i
              @click.prevent="deleteRow(scope.$index, scope.row)"
              class="el-icon-delete">
            </i>
          </template>
        </el-table-column>
      </el-table>
    </el-form>
    <div slot="footer">
      <el-button size="medium" @click="closeDialog">取消</el-button>
      <el-button size="medium" type="primary" ref="saveButton" @click="saveData('formRef')">保存</el-button>
    </div>
  </el-dialog>
</template>

<script>
export default {
  data() {
    return {
      dialogVisible: false,
      tableData: [
        {
          invoiceTypeCode: ['1'],
          taxCategory: '',
          taxRate: '',
          dateRange: []
        }
      ],
      typeList: [
        { invoiceTypeCode: '1', invoiceTypeName: '增值税专用发票' },
        { invoiceTypeCode: '2', invoiceTypeName: '增值税普通发票' }
      ]
    };
  },
  methods: {
    resetForm(formName) {
      this.$refs[formName].resetFields();
    },
    beforeClose(done) {
      this.resetForm('formRef');
      done();
    },
    deleteRow(index, row) {
      this.tableData.splice(index, 1);
    },
    closeDialog() {
      this.dialogVisible = false;
      this.resetForm('formRef');
    },
    saveData(formName) {
      this.$refs[formName].validate(valid => {
        if (valid) {
          console.log(this.tableData);
          this.closeDialog();
        }
      });
    },
    addNewRule() {
      this.tableData.push({
        invoiceTypeCode: [],
        taxCategory: '',
        taxRate: '',
        dateRange: [],
        isDisabled: false
      });
    },
    renderHeader(h, { column }) {
      return h(
        'div',
        [
          h('span', column.label),
          h('i', {
            class: 'el-icon-circle-plus',
            style: 'color: #409eff; font-size: 24px; cursor: pointer;',
            on: {
              click: this.addNewRule
            }
          })
        ]
      );
    }
  }
};
</script>

<style scoped>
.custom-dialog .el-dialog__body {
  padding: 20px;
}

.custom-table {
  margin-bottom: 20px;
}

.custom-table td, .custom-table .cell {
  padding: 0px;
}

.custom-table .el-input__inner {
  border-radius: 0;
}

.custom-table .el-icon-delete {
  cursor: pointer;
}

.custom-dialog .el-dialog__header {
  background: rgb(2, 65, 114);
  color: #fff;

  .el-dialog__title,
  .el-icon {
    color: #fff;
  }
}
</style>

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

火语言RPA流程组件介绍--文件系统监控

&#x1f6a9;【组件功能】&#xff1a;监控指定文件夹或文件的创建、变更删除等事件 配置预览 配置说明 事件类型 “异步回调处理”、“同步等待”2种类型供选择。流程是否等待发生监控文件的创建、变更、删除事件&#xff0c;异步不等待&#xff0c;同步则等待。 监控文件…

MySQL创建数据库和表应用教程

前言 MySQL 是一种流行的关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;广泛应用于 web 应用开发中。以下是一个简单的 MySQL 创建数据库和表的教程&#xff0c;涵盖了基本步骤。假设你已经安装了 MySQL 并且能够通过命令行或 MySQL Workbench 等工具访问它。…

【网络安全】服务基础第一阶段——第五节:Windows系统管理基础---- DHCP部署与安全

目录 一、DHCP协议 理解DHCP握手&#xff1a; 分配IP地址方式&#xff1a; DHCP协议报文的种类&#xff1a; DHCP协议工作过程&#xff1a; ​编辑DHCP四个阶段&#xff1a; 续约租期&#xff1a; 重新连接使用IP地址&#xff1a; DHCP安全性&#xff1a; 二、DHCP中继…

海龟交易系统所代表的传统CTA策略是不是过时了?

原创内容第639篇&#xff0c;专注量化投资、个人成长与财富自由。 量化投资具体步骤&#xff1a;数据、指标&#xff08;因子&#xff09;&#xff0c;信号规则或因子合成&#xff0c;策略&#xff0c;绩效评估&#xff0c;风控。 其实所有的策略都可以归结为以上的步骤。 我…

Redis 篇-深入了解查询缓存与缓存所带来的问题(读写不一致、缓存穿透、缓存雪崩、缓存击穿)

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 本章目录 1.0 什么是缓存 2.0 项目中具体如何添加缓存 3.0 添加缓存后所带来的问题 3.1 读写不一致问题 3.1.1 缓存更新策略 3.1.2 具体实现缓存与数据库的双写一致 3.2 缓存穿…

DAC专用功能芯片TI DAC8562/8563

DAC8563具有 2.5V、4ppm/C 基准的 16 位、双通道、低功耗、超低短时脉冲波形干扰、缓冲电压输出 DAC。 DAC8562是一款16位、双通道、串行接口的DAC&#xff0c;采用SPI接口进行通信&#xff0c;具有内部参考电压、软件可编程增益和输出保护等功能。 一、DAC8563的主要参数 供…

JVM面试(二)内存区域划分

内存区划分 Java虚拟机在执行Java程序的过程中会把它锁管理的内存划分为若干个不同的数据区域。 这些区域有各自不同的用途&#xff0c;以及创建和销毁的时间。 有的区域随着虚拟机的进程一直存在&#xff0c;有的区域依赖用户线程的启动和结束而建立和销毁。 根据《Java虚拟…

YOLOv8 训练15种动物分类模型

1. 下载数据集 https://hyper.ai/datasets/31084 2. 进行训练 这里数据集没做拆分&#xff0c;训练测试都是同一个数据集。 train.py:python from ultralytics import YOLO from ultralytics.utils import DEFAULT_CFG from datetime import datetimecurrent_time datetim…

2.1CPU内部结构

&#x1f393; 微机原理考点专栏&#xff08;通篇免费&#xff09; 欢迎来到我的微机原理专栏&#xff01;我将帮助你在最短时间内掌握微机原理的核心内容&#xff0c;为你的考研或期末考试保驾护航。 为什么选择我的视频&#xff1f; 全程考点讲解&#xff1a;每一节视频都…

利用深度学习实现验证码识别-3-ResNet18

在当今数字化时代&#xff0c;验证码作为一种重要的安全验证手段&#xff0c;广泛应用于各种网络场景。然而&#xff0c;传统的验证码识别方法往往效率低下&#xff0c;准确率不高。今天&#xff0c;我们将介绍一种基于 ResNet18 的验证码识别方法&#xff0c;它能够高效、准确…

AI大模型优化技巧:参数高效微调(PEFT)与LoRA微调深度解析

1. Fine-tuning 相较于基础大模型动辄万卡的代价&#xff0c;微调可能是普通个人或者企业少数能够接受的后训练大模型(post-training)的方式。 微调是指在一个预训练模型(pre-training)的基础上&#xff0c;通过少量的数据和计算资源&#xff0c;对模型进行进一步训练&#x…

阿里巴巴数学竞赛成绩未公布:背后的权衡与期待

文 | 头部财经首席评论员白立新 发布 | 头部财经 top168.com 导语&#xff1a;2024 年阿里巴巴数学竞赛成绩迟未公布&#xff0c;引发广泛猜测。中专生姜萍的表现备受瞩目&#xff0c;达摩院陷入两难困境。这场竞赛结果的公布&#xff0c;关乎多方利益与社会影响&#xff0c;…

UML(ER) manual book

图形与符号 实体 真实世界的表示&#xff08;实物&#xff09;&#xff0c;负责数据的发送或者接收&#xff0c;通常使用矩形表示。 处理和加工 通常使用圆圈表示数据时如何被处理&#xff0c;比如下订单&#xff0c;付款等动作。 数据存储 通常使用两条平行线表示&…

碲化镉太阳能电池:绿色能源的新星,高效转换引领未来

随着全球对清洁能源需求的持续增长和技术的不断进步&#xff0c;碲化镉太阳能电池必将在未来的能源市场中占据重要地位。‌‌PicoQuant公司一直致力于碲化镉太阳能电池新材料、‌新工艺的探索与研发&#xff0c;充分利用其在时间分辨技术上的优势&#xff0c;‌为碲化镉太阳能电…

5、LVGL控件-滑轮、滑动条、圆弧

本篇文章目录导航 ♠♠ LVGL控件-滑轮、滑动条、圆弧 ♣♣♣♣ 一、LVGL 滑轮部件 ♦♦♦♦♦♦♦♦ 1.1 滑轮部件组成部分 ♦♦♦♦♦♦♦♦ 1.2 滑轮部件基本API ♦♦♦♦♦♦♦♦ 1.3 实验小演示 ♣♣♣♣ 二、LVGL 滑动条部件 ♦♦♦♦♦♦♦♦ 2.1 滑动条部件组成部分 ♦…

论文阅读:MambaVision: A Hybrid Mamba-Transformer Vision Backbone

论文地址&#xff1a;arxiv 摘要 作者提出了一种新型的混合 Mamba-Transformer 主干网络。通过重新设计 Mamba 公式&#xff0c;增强了其高效建模视觉特征的能力。 此外&#xff0c;作者还通过对 ViT 与 Mamba 消融研究&#xff0c;实验结果表明了&#xff1a;在最后几层为 …

“双碳”减排背景下企业自发电系统该具备哪些功能?

随着全球能源危机加剧、用能需求上升以及新能源技术的迅速发展&#xff0c;新能源发电的应用范围不断扩大&#xff0c;并逐步形成了新型能源与电力市场。然而&#xff0c;由于新能源的能量密度普遍较低&#xff0c;进行大规模发电时需精心挑选适合的位置&#xff0c;因此新能源…

【网络安全】服务基础第一阶段——第九节:Windows系统管理基础---- Windows_AD域

目录 一、域与活动目录 1.1 工作组 1.2 域 1.2.1 域&#xff08;Domain&#xff09; 1.2.2 域控制器&#xff08;Domain Controller&#xff0c;DC&#xff09; 1.2.3 功能和角色 1.2.4 管理和监控 1.2 5 域结构 1.3 组织单元&#xff08;Organizational Unit&#xff…

Seata 的4种事务模式(XA、AT、TCC、SAGA)

目录 前言 Seata架构 事务模式 XA AT TCC 区别 前言 在分布式系统中&#xff0c;实现一个功能可能需要由几个不同的服务来共同实现。这就会带来一个问题&#xff0c;不同的服务之间无法做到使用同一个事务&#xff0c;这就无法保证数据的一致性了。在一些对数据一致性要…

基于SSM的“基于决策树算法的大学生就业预测系统”的设计与实现(源码+数据库+文档)

基于SSM的“基于决策树算法的大学生就业预测系统”的设计与实现&#xff08;源码数据库文档) 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SSM 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 系统用户用例图 学校基础信息管理 毕业生基…