vxe-table 实现表格填写自动计算且限制数值的复杂操作

news2024/10/5 21:30:34

vxe-table 实现表格填写自动计算且限制数值复杂操作

效果

演示

在这里插入图片描述

思路

  1. 输入框设置最大值 :max="row.max"
  2. 输入框调用方法@blur="updateFooterEvent(row, $event)" @input=" if (row[item.field] > row.max) { row[item.field] = row.max; } "

上代码

核心代码

设置最大值

controlrowcell({ row, column }: any) {
      this.setMax(column.title, row);
      return true;
    },
setMax(field: any, row: any) {
      let max = row.detailqty;
      for (const key in row) {
        if (key !== "detailqty" && key !== "deptId" && key !== "spe" && key !== "deptName" && key !== "id" && key !== "_XID" && key !== "partname" && key !== field && key !== "" && key !== "max") {
          console.log(key);
          max -= row[key];
        }
      }
      row.max = max;
      console.log(row.max);
    },
    updateFooterEvent(row: any, event: any) {
      console.log(row);
      console.log(event.value);
      let spe = row.max - event.value;
      let qty = row.detailqty;
      row.spe = qty + "/" + spe;
    },
res.data.map((v: any) => {
			//业务所需自行修改
            if (v.partname.indexOf("机架") !== -1) {
              v.spe = v.detailqty + "/0";
            } else {
              let spe = v.detailqty;
              for (const key in v) {
                if (key !== "detailqty" && key !== "deptId" && key !== "spe" && key !== "deptName" && key !== "id" && key !== "_XID" && key !== "partname" && key !== "" && key !== "max") {
                  spe -= v[key];
                }
              }
              v.spe = v.detailqty + "/" + spe;
              v.max = spe;
            }
          });

输入框设置

在这里插入代码片<vxe-column v-for="item in columnList" :key="item.field" :field="item.field" :title="item.title" :edit-render="{}" min-width="100">
          <template #edit="{ row }">
            <vxe-input
              v-model="row[item.field]"
              type="number"
              :max="row.max"
              placeholder="请输入"
              @blur="updateFooterEvent(row, $event)"
              @input="
                if (row[item.field] > row.max) {
                  row[item.field] = row.max;
                }
              "
            ></vxe-input>
          </template>
        </vxe-column>

完整代码

template部分

<!-- 表格 -->
      <vxe-toolbar>
        <template #buttons>
          <vxe-button @click="insertEvent(0)">新增</vxe-button>
          <vxe-button @click="deleteSelect">删除</vxe-button>
        </template>
      </vxe-toolbar>

      <vxe-table
        ref="xTable"
        border
        show-footer
        show-overflow
        :loading="loading"
        :data="partData"
        :column-config="{ resizable: false }"
        :edit-config="{ showIcon: false, trigger: 'click', mode: 'cell', activeMethod: controlrowcell }"
        :footer-method="footerMethod"
        :row-config="{ isHover: true }"
        :export-config="{}"
        class="editable-footer"
      >
        <vxe-column type="checkbox" width="50" fixed="left"></vxe-column>
        <vxe-column type="seq" title="序号" width="50" fixed="left"></vxe-column>
        <vxe-column v-for="item in columnList" :key="item.field" :field="item.field" :title="item.title" :edit-render="{}" min-width="100">
          <template #edit="{ row }">
            <vxe-input
              v-model="row[item.field]"
              type="number"
              :max="row.max"
              placeholder="请输入"
              @blur="updateFooterEvent(row, $event)"
              @input="
                if (row[item.field] > row.max) {
                  row[item.field] = row.max;
                }
              "
            ></vxe-input>
          </template>
        </vxe-column>
      </vxe-table>

script部分

<script lang="ts">
import { defineComponent, reactive } from "vue";
import baseService from "@/service/baseService";
export default defineComponent({
  setup() {
    return reactive({
      visible: false as boolean,
      loading: false as boolean,
      proPlan: {
        id: "",
        dateValue: [] as any
      } as any,
      columnList: [] as any,
      partData: [] as any,
      partList: [] as any,
      allPart: [] as any,
      oldval: 0
    });
  },
  methods: {
    controlrowcell({ row, column, columnIndex }: any) {
      this.setMax(column.title, row);
      return true;
    },
    // 设置当前点击单元格输入框的最大值
    setMax(field: any, row: any) {
      let max = row.detailqty;
      for (const key in row) {
        if (key !== "detailqty" && key !== "deptId" && key !== "spe" && key !== "deptName" && key !== "id" && key !== "_XID" && key !== "partname" && key !== field && key !== "" && key !== "max") {
          console.log(key);
          max -= row[key];
        }
      }
      row.max = max;
      console.log(row.max);
    },
    updateFooterEvent(row: any, event: any) {
      console.log(row);
      console.log(event.value);
      let spe = row.max - event.value;
      let qty = row.detailqty;
      row.spe = qty + "/" + spe;
    },
    deleteSelect() {
      const $table = this.$refs.xTable;
      const selectRecords = $table.getCheckboxRecords();
      if (selectRecords.length === 0) {
        this.$message.error("至少选择一条数据!");
        return false;
      }
      $table.removeCheckboxRow();
    },
    async insertEvent(row: any) {
      const $table = this.$refs.xTable;
      const record = {
        type: "add",
        partname: "",
        deptName: "",
        deptId: ""
      };
      const { row: newRow } = await $table.insertAt(record, row);
      await $table.setActiveCell(newRow, "partname");
    },
    changeDept(e: any) {
      for (let i = 0; i < this.deptList.length; i++) {
        if (e === this.deptList[i].id) {
          this.handDepData(e, this.deptList[i].name);
        }
      }
    },
    handDepData(id: any, name: any) {
      if (this.partData.length === 0) {
        return;
      }
      for (let i = 0; i < this.partData.length; i++) {
        if (this.partData[i].deptName == null || !this.partData[i].deptName) {
          this.partData[i].deptName = name;
          this.partData[i].deptId = id;
          this.$refs.xTable.isUpdateByRow(this.partData[i]);
        }
      }
    },
    selectPart(row: any) {
      for (let i = 0; i < this.partList.length; i++) {
        if (this.partList[i].id === row.id) {
          row.partname = this.partList[i].partname;
          row.detailqty = this.partList[i].detailqty;
        }
      }
    },
    selectDept(row: any) {
      console.log(row);
      for (let i = 0; i < this.deptList.length; i++) {
        if (this.deptList[i].id === row.id) {
          row.deptName = this.deptList[i].name;
          row.deptId = this.deptList[i].id;
        }
      }
    },
    footerMethod({ columns, data }: any) {
      return [
        columns.map((column: { property: string }, columnIndex: number) => {
          if (columnIndex === 0) {
            return "";
          }
          if (columnIndex === 1) {
            return "汇总";
          }
          if (!["partname", "deptId"].includes(column.property)) {
            if (column.property === "spe") {
              return this.sumNum(data, "detailqty");
            }
            return this.sumNum(data, column.property);
          }
          return null;
        }),
        columns.map((column: { property: string }, columnIndex: number) => {
          if (columnIndex === 0) {
            return "";
          }
          if (columnIndex === 1) {
            return "人数";
          }
          if (!["partname", "deptId"].includes(column.property)) {
            if (this.capDate.length > 0) {
              for (let i = 0; i < this.capDate.length; i++) {
                if (this.capDate[i].date.includes(column.property)) {
                  return this.sumPerson(data, column.property, Number(this.capDate[i].number));
                }
              }
            }
          }
          return null;
        })
      ];
    },
    sumNum(list: { [x: string]: any }[], field: string | number) {
      let count = 0;
      list.forEach((item: { [x: string]: any }) => {
        if (item[field]) {
          count += Number(item[field]);
        }
      });
      return count;
    },
    sumPerson(list: { [x: string]: any }[], field: string | number, num: number) {
      let count = 0;
      list.forEach((item: { [x: string]: any }) => {
        if (item[field]) {
          count += Number(item[field]);
        }
      });
      return Math.ceil(count / num);
    },
    /**
     * 获取计划明细信息
     */
    getInfo() {
      if (this.plan.id) {
        this.loading = true;
        this.proPlan = this.plan;
        this.proPlan.dateValue = [];
        if (this.plan.startdate || this.plan.enddate) {
          this.proPlan.dateValue.push(this.plan.startdate);
          this.proPlan.dateValue.push(this.plan.enddate);
        }
        this.changeDate(this.proPlan.dateValue);
        baseService.get("xxxx", { planId: this.plan.id }).then((res) => {
          if (res.code !== 0) {
            return this.$message.error(res.msg);
          }
          console.log(res.data);
          res.data.map((v: any) => {
            if (v.partname.indexOf("机架") !== -1) {
              v.spe = v.detailqty + "/0";
            } else {
              let spe = v.detailqty;
              for (const key in v) {
                if (key !== "detailqty" && key !== "deptId" && key !== "spe" && key !== "deptName" && key !== "id" && key !== "_XID" && key !== "partname" && key !== "" && key !== "max") {
                  spe -= v[key];
                }
              }
              v.spe = v.detailqty + "/" + spe;
              v.max = spe;
            }
          });
          this.partData = res.data;
          this.getPart(this.plan.bdEquipId, res.data);
          this.loading = false;
        });
      }
    },
    /**
     * 根据时间加载列
     * @param val
     */
    changeDate(val: any) {
      console.log(val.length > 0);
      if (val.length > 0) {
        this.getCapDate(val);
      }
    },
    InitColumns(val: any) {
      let all = this.getAll(val[0], val[1]);
      this.columnList = reactive([]);
      for (let i = 0; i < all.length; i++) {
        let column = reactive({
          field: all[i],
          title: all[i]
        });
        this.columnList.push(column);
      }
      //排序
      this.columnList.sort(function (A: number, B: number) {
        return A - B;
      });
    },
    /**
     * 根据时间加载 每一天时间
     * @param start 开始时间
     * @param end 结束时间
     */
    getAll(start: any, end: any) {
      let dateList = [];
      let startTime = this.getDate(start);
      let endTime = this.getDate(end);

      while (endTime.getTime() - startTime.getTime() >= 0) {
        let year = startTime.getFullYear();
        let month = startTime.getMonth() + 1 < 10 ? "0" + (startTime.getMonth() + 1) : startTime.getMonth() + 1;
        let day = startTime.getDate().toString().length == 1 ? "0" + startTime.getDate() : startTime.getDate();
        dateList.push(year + "-" + month + "-" + day);
        startTime.setDate(startTime.getDate() + 1);
      }
      return dateList;
    },
    /**
     * 时间格式处理 2022-11-11
     * @param datestr 传入的时间
     */
    getDate(datestr: any) {
      let temp = datestr.split("-");
      return new Date(temp[0], temp[1] - 1, temp[2]);
    }
});
</script>

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

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

相关文章

我们是如何追逐元宇宙、XR等“概念股”浪潮的?

作者&#xff1a;金擘(渚薰) 1.今年我们迈出的第一步 随着淘宝人生小屋项目的正式上线&#xff0c;淘宝人生今年的元宇宙规划初步成型。 加上在 S1 同淘宝直播团队的合作上线的 Disney 毛毛狂欢馆&#xff0c;我们也正式迈出了“元宇宙”技术的第一步。 今年是淘宝人生上线 3…

数智技术,企业绿色低碳转型的催化剂?大咖说新一期每周推荐来袭!

“双碳”战略下&#xff0c;企业会遇到哪些机遇和挑战&#xff1f;中小企业如何实现绿色转型&#xff1f;数字化又在其中发挥了怎样的作用&#xff1f; 介绍&#xff1a; 阿里云能耗云总经理 周文闻 施耐德电气首席数字化设计师 毛春景 “双碳”战略下&#xff0c;企业会遇到…

你写过哪些有趣的python?(附零基础学习资料)

前言 某网站上有个浏览超过400万的问题&#xff1a;可以用 Python 编程语言做哪些神奇好玩的事情&#xff1f; 我先举一个很不专业的栗子… 然后再找几个人抬一堆例子来… 不是很稀饭《复联》嘛&#xff0c;看了《复联4》&#xff0c;就用50行Python代码做了这些&#xff1a;…

Word控件Spire.Doc 【超链接】教程(4):如何修改Word文档中的超文本

Spire.Doc for .NET是一款专门对 Word 文档进行操作的 .NET 类库。在于帮助开发人员无需安装 Microsoft Word情况下&#xff0c;轻松快捷高效地创建、编辑、转换和打印 Microsoft Word 文档。拥有近10年专业开发经验Spire系列办公文档开发工具&#xff0c;专注于创建、编辑、转…

【leetcode】从前序与中序遍历序列构造二叉树

一、题目描述 给定两个整数数组 preorder 和 inorder &#xff0c;其中 preorder 是二叉树的先序遍历&#xff0c; inorder 是同一棵树的中序遍历&#xff0c;请构造二叉树并返回其根节点。 示例1&#xff1a; 输入: preorder [3,9,20,15,7], inorder [9,3,15,20,7] 输出:…

rk3399-uboot2017-增加串口通信

一、主要还是解决这个问题&#xff0c;最后没办法&#xff0c;只能进行串口通信&#xff0c;来识别屏幕的类型了。 基本步骤如下&#xff1a; 1. uboot阶段发送串口指令&#xff0c;等待串口回复数据&#xff0c;根据数据识别屏幕类型 2.在bootargs增加一个自定义的参数&…

一个完整的项目是如何开展的:对项目生涯的总结

我正在参加「掘金启航计划」 变量的类型指的是变量的特性或特征&#xff0c;比如表示数字类型、文本类型、集合类型等&#xff0c;表示的是一类数据。 Dart提供以下的内置类型&#xff1a; 数字&#xff1a;int, double (整型(表示整数)&#xff0c;浮点型(表示小数))布尔&a…

程序员如何平衡主业和副业?

什么是副业&#xff1f; 对于副业的定义&#xff0c;每个人都有自己的见解。不过对大部分人来说&#xff0c;副业相对于主业而言&#xff0c;就是工作日朝九晚五的工作称为主业&#xff0c;其他时间做的赚钱的项目或者工作可以称之为副 副业可以是写文章、拍视频、打代码&…

干扰管理学习日志8-------多用户联合_资源卸载_功率分配_计算资源分配

目录一、文章概述二、系统模型环境三、理论模型1.系统目标2.约束条件3.公式推导四、算法设计1.上行链路功率分配策略(1)任务目标(2)伪代码2.中央服务器算力分配策略3.任务卸载策略(1)任务目标(2)卸载集缩小条件(3)卸载集扩充条件(4)策略(5)伪代码五、性能表征本文是对论文《Mul…

[Linux]----初始网络

文章目录前言一、计算机网络的背景重新看待计算机结构网络发展认识"协议"二、网络协议初始软件分层协议分层OSI七层模型TCP/IP五层(四层)模型三、网络传输的基本流程网络和操作系统之间的关系局域网通信的原理四、数据包的封装和分用五、网络中的地址管理认识IP地址认…

2004-2020年全国30省工业污染治理完成投资数据

2004-2020年全国30省工业污染治理完成投资数据 1、时间&#xff1a;2004-2020年 2、范围&#xff1a;包括全国30个省&#xff0c;不含西藏 3、来源&#xff1a;国家统计J 4、缺失情况说明&#xff1a;无缺失 5、指标说明&#xff1a; 目前虽然采取了一系列环境规制相关政…

[附源码]Python计算机毕业设计SSM基于Web学术会议投稿管理系统(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

二元灰狼优化(BGWO)应用于特征选择任务(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f468;‍&#x1f4bb;4 Matlab代码 &#x1f4a5;1 概述 特征选择是当前信息领域,尤其是模式识别领域的研究热点。该代码演示了BGWO如何使用基准数据集Main解决特征选择问题。 &#…

python国际化课程capstone(ML预测ACM队员获奖概率)

目录 前言 原始数据集 爬虫部分 爬取每个队员在buct做题数量 爬取每个队员codeforces的最高分&#xff0c;注册时间&#xff0c;解题数量 爬取每个队员有效做题时间 数据处理部分 模型部分 Linear Regression XGBregressiongridsearchCV调参 Random Forset 前言 刚…

Redis框架(九):大众点评项目 缓存工具封装

大众点评项目 缓存工具封装需求&#xff1a;缓存工具封装业务实现代码总览总结SpringCloud章节复习已经过去&#xff0c;新的章节Redis开始了&#xff0c;这个章节中将会回顾Redis实战项目 大众点评 主要依照以下几个原则 基础实战的Demo和Coding上传到我的代码仓库在原有基础…

视频直播技术干货:一文读懂主流视频直播系统的推拉流架构、传输协议等

1、引言 随着移动网络网速的提升与资费的降低&#xff0c;视频直播作为一个新的娱乐方式已经被越来越多的用户逐渐接受。特别是最近这几年&#xff0c;视频直播已经不仅仅被运用在传统的秀场、游戏类板块&#xff0c;更是作为电商的一种新模式得到迅速成长。 本文将通过介绍实时…

爆火Chatgpt注册完全指南

1 chatgpt 简介 ChatGPT是一种语言模型&#xff0c;它被训练来对对话进行建模。它能够通过学习和理解人类语言来进行对话&#xff0c;并能够生成适当的响应。ChatGPT使用了一种叫做Transformer的神经网络架构&#xff0c;这是一种用于处理序列数据的模型&#xff0c;能够在输入…

第33篇 网络(三)FTP(一)

导语 上一节我们讲述了HTTP的编程&#xff0c;这一节讲述与其及其相似的FTP的编程。FTP即FileTransfer Protocol&#xff0c;也就是文件传输协议。FTP的主要作用&#xff0c;就是让用户连接上一个远程计算机&#xff0c;查看远程计算机有哪些文件&#xff0c;然后把文件从远程…

STM32F4 | STM32CubeMX 图形配置工具

文章目录一、STM32CubeMX 简介二、STM32CubeMX 运行环境搭建1.Java环境安装2.STM32CubeMX 图形化工具安装三、使用 STM32CubeMX 工具配置工程模板1.工程初步建立和保存2.RCC 设置3.时钟系统&#xff08;时钟树&#xff09;配置4.GPIO 功能引脚配置5.生成工程源码6.编写用户程序…

汽车行业:充分借力数据价值,推动数字化营销链路闭环

当下&#xff0c;汽车行业已慢慢由曾经的增量市场逐步转变为存量市场。更年轻的消费群体偏好、更精准智能的营销投放策略和强势入局的新能源汽车等因素都在推动着汽车行业的不断发展。对于汽车厂商和垂域媒体来说&#xff0c;进行丰富的人群洞察与用户分层&#xff0c;能挖掘更…