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

2023-05-16

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>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

  • 面试:每发送一个http请求就要建立一个tcp连接吗(非持久连接/持久连接)

    非持久连接 xff1a HTTP 1 0 中 的首部字段Connection 默认值为 close xff0c 即每次请求都会重新建立和断开 TCP 连接 持久连接 xff1a HTTP 1 1 中 的首部字段Connection 默认值为
  • 实例:用C#.NET手把手教你做微信公众号开发(16)--事件消息处理之点击菜单2

    微信用户点击菜单时 xff0c 会通过微信服务器转发两种事件给你的服务器 xff0c 一种是拉取消息时的事件推送 xff1b 另一种是跳转链接时的事件推送 上篇讲了第一种 xff0c 本篇先讲第二种 一 消息格式 推送XML数据包示例 xf
  • 合理清除AlibabaProtect进程

    1 在 任务管理器 的 进程选项中 xff0c 找到AlibabaProtect进程 xff0c 单击后 xff0c 右键选择 打开文件所在位置 xff0c 找到该进程对应文件所在位置 xff0c 并将其上级目录做成 桌面快捷方式 xff0
  • Sublime Text 4安装使用(完整教程)

    Sublime Text 4安装使用 安装使用语言汉化 OK啦 xff0c 觉得有用的点个赞吧 xff01 xff01 xff01 写这篇博客的意义希望能够将我走过的路 踩过的坑记录下来 在后来在遇到的时候能够更好的翻阅 未经允许 xff0
  • Xlaunch启动后无法显示图形界面,提示connection refused

    解决方案 xff1a 重启远程端
  • 【PR】零基础快速入门教程

    PR 零基础快速入门教程 PR xff08 Premiere xff09 能做什么 xff1f PR欢迎界面及新建项目工作区及窗口说明导入文件建立序列视频剪辑添加字幕导出视频 使用软件 xff1a Premiere2020 新年卷起来 xf
  • 【PR】源窗口

    PR 源窗口 源窗口粗剪源窗口按钮功能标记按钮出入点相关插入与覆盖插入覆盖 导出帧 使用软件 xff1a Premiere2020 源窗口粗剪 我们手上可能有一些很长的视频 xff0c 但是我就想要其中的几段 xff0c 这个时候粗剪就很方
  • 【PR】时间轴窗口

    PR 时间轴窗口 时间轴窗口工具按钮 视频轨道切换轨道输出切换同步锁定目标切换轨道锁定轨道对插入和覆盖进行源修补 工具按钮 音频轨道静音轨道独奏轨道画外音录制 时间轴窗口基础操作添加轨道查看完成视频和音频缩放轨道删除轨道 添加关键帧 使用软
  • 【PR】来,一起做一个简单的剪辑视频吧

    PR 来 xff0c 一起做一个简单的剪辑视频吧 前言新建项目导入素材创建序列裁剪视频视频导入序列 图片背景音频处理多视频素材处理添加字幕导出上传学了上面能做到什么程度 xff1f 可以看一下我用上面的方法做出成品 新手教程哈 xff0c
  • 【PR】视频剪裁

    PR 视频剪裁 把素材文件导入PR问题1 xff1a 删除多余部分 xff08 主要是录制范围 xff09 导出视频 xff08 问题1解决方案看我 xff09 问题2 导出的视频还有黑边导出视频 xff08 问题2解决方案看我 xff09
  • 【PR】图片处理

    PR 图片处理 导入图片将图片文件拖拽进时间轴点击图片选择效果 xff08 时间轴上的那个条 xff09 改变图片位置修改图片大小图片不透明度旋转与锚点 xff08 视频层 xff09 图层 PR不光能导入视频 xff0c 还可以导入图片
  • 【PR】音频处理及过度效果

    PR 音频处理及过度效果 导入音频插入时间轴中的A轨道 xff08 声音轨道 xff09 音频处理调整音量 音频剪贴音频过度效果淡入 xff0c 淡出 xff0c 过度淡入淡出过度 工具按钮 音频轨道 xff08 不充内容 xff0c 可以
  • 实例:用C#.NET手把手教你做微信公众号开发(17)--公众号主动给粉丝发信息之模板消息

    前面讲了那么多 xff0c 都是微信用户主动向公众号发送信息或某个操作触发公众号响应并给予用户回复 如果在微信用户没有主动发起互动的情况下 xff0c 公众号应该如何向微信用户发送消息呢 xff1f 本篇给出一种解决方案 xff1a 模板消
  • 【PR】视频转场与视频粗剪

    PR 视频转场与视频粗剪 视频转场转场使用方法 粗剪与标记 xff08 多个视频合并的小技巧 xff0c 可以不看 xff09 粗剪标注 今天我们来搞一下视频 xff0c 主要是搞一下转场效果 转场 xff1a 让不同场景的画面间过渡更加自
  • 【PR】字幕处理

    PR 字幕处理 添加字幕新建字幕基础设置多字幕添加 其他调整基础效果 效果控件 字幕特效 PR2022版本有字幕插件 xff0c 可以更轻松的处理字幕 我用的是PR2020 xff0c 没有这个功能 xff0c 只能一个一个添加 xff0c
  • 【外设零基础通用教程】GPIO 上

    外设零基础通用教程 GPIO 上 视频 文章结构外设 xff1a GPIO代码编写GPIO输入方法GPIO输出方法 视频地址 xff1a 咸鱼的外设通用教程之GPIO 本教程适合 xff1a 硬件零基础纯小白 上手了硬件不知从何开始 xff
  • 【外设零基础通用教程】GPIO 下

    外设零基础通用教程 GPIO 下 使用方法GPIO 值输入读取值输出设置值 GPIO输入输出应用GPIO输入应用GPIO输出应用文档使用 理论补充输出方式推挽输出开漏输出 上篇连接 xff1a 外设零基础通用教程 GPIO 上 xff0c
  • 硬件外设使用方法——GPIO

    硬件外设使用 GPIO用法 GPIO基本概念GPIO应用pyb与micropython什么是pyb什么是micropythonpyb与micropython关系 GPIO在micropython中的用法什么是pyb库pyb库中的GPIO用法
  • 【硬件外设使用】——ADC

    硬件外设使用 ADC ADC基本概念ADC使用方法pyb adcmachine adc ADC可用的传感器 ADC基本概念 ADC是模拟数字转换器 xff08 Analog to Digital Converter xff09 的缩写 xf
  • 【硬件外设使用】——DAC

    硬件外设使用 DAC DAC基本概念DAC使用方法pyb dacmachine dac DAC可用的传感器 DAC基本概念 DAC是数字模拟转换器 xff08 Digital to Analog Converter xff09 xff08

随机推荐