vxe-table 实现表格填写自动计算且限制数值复杂操作
效果
演示
思路
- 输入框设置最大值
:max="row.max"
- 输入框调用方法
@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>