先上效果图:
说明: 横 和 纵 都是遍历出来的 从数据库取出来的
input 是一个个填的 最下面有一个提交保存的按钮
跟这个表格很类似:
一、问题是这样的:后台传了xArr = [x1, x2,...,xn]和yArr = [y1, y2, ..yn]两个数组,前端要渲染出表格并且可以填写每个单元格的值,然后按照一定数据结构保存并传给后台,并且再次获取这个数据结构和数组xArr、yArr可以自己渲染出这个表?实现新增和修改的功能;
y1, y2,...,yn作为列名,x1,x2, ..., xn作为第一列数据,此业务模型是一种常见的表格,只不过要求行列都不固定,由后台数据提供并且动态生成。还要能够实现修改功能。本质上是一个动态渲染可编辑Table的问题。难点在于动态构建表格并且实现数据展示和保存。
二、思路:
(1)数据转换成表格后,处理起来就简单了,如果以常见的Table组件为例,只需要构建columns和dataSource两个数组数据即可渲染出表格;
(2)渲染出表格后,表格每一个余下的单元格都要可输入,可以考虑单元格利用render渲染出Input组件,通过Input的操作onChange或onBlur去改变数据并存储。
(3)数组是引用类型,可以利用引用类型只要没有深拷贝或改变指针指向内存地址就不变的原理,方便记录操作后的数据。
三、解决方法:
(1)动态构建columns(表格列数据)和dataSource(表格数据源)渲染出表格。(Table可参考 https://ant.design/components/table-cn/#header)
表格添加Input并且根据onChange/onBlur事件动态记录dataSource的变化。
四、19年的完整代码:
<template>
<!-- 广播播放优先级配置管理 -->
<div class="staple">
<div class="listfile">
<Row>
<Col span="24">广播播放优先级配置管理</Col>
</Row>
<Table border ref="selection" :columns="historyColumns" :data="historyData" height="500">
<!-- <Table border ref="selection" :columns="historyColumns" :data="historyData" height="500" id="tips" v-on:mouseenter="visible" @mouseleave="invisible"> -->
<span v-show="seen">123</span>
</Table>
<div slot="footer" style="margin-top:10px;">
<Row :gutter="20" type="flex" justify="end">
<Col span="2">
<Button type="primary" long @click="handleSave()">保存</Button>
</Col>
<Col span="2">
<Button long @click="cancelAdd()">取消</Button>
</Col>
</Row>
</div>
</div>
</div>
</template>
<script>
import Cookies from "js-cookie";
export default {
// el:"#tips",
data() {
const letter = this.$store.state.parameter.deserve; //字典
return {
seen: false,
priorityType: letter.M407, //优先级类型(数据字典M407)
broadcastinfoType: letter.M408, //广播信息类型(数据字典M408)
historyColumns: [
{ title: "#", key: "key", align: "center" },
{
title: "优先级类型A",key: "priorityType",align: "center",
render: (h, params) => {
return h("Input", {
props: {
// type: 'primary',
placeholder: "请输入...",
value: params.row.priorityType
}
}
// params.row.priorityType
);
}
},
{ title: "广播信息类型B",key: "broadcastinfoType",align: "center",
render: (h, params) => {
return h("Input", {
props: {
placeholder: "请输入...",
value: params.row.broadcastinfoType
}
});
}
}
],
historyData: [],
record: [], // 修改后的值
originData: [], // 存放接口数据的
list:[], // 数据库--初始化
// 提交的变量
editAll: {
priorityInfoList: []
}
};
},
methods: {
initSql() {
// 根据 字典 补全数据库数据
let list = []; // 全部的数据 的初始值 level 都为 0
this.priorityType.map( v => {
this.broadcastinfoType.map( item => {
list.push({
broadcastinfoType: item.itemValue,
priorityType: v.itemValue,
level: 0,
lastmodifytime: "2019-03-25 00:00:00",
reamrk: "123456",
createuserid:this.$store.state.user.userId,
createusername: this.$store.state.user.userName,
})
})
})
// console.log("list:",list);
// 2 调一下 接口 得到
// 查询所有
this.$axios({
method: "get",
url: this.baseURL + "/priority/PriorityInfo/list_All",
})
.then(res => {
// console.log("接口:", res.data);
this.originData = res.data;
// console.log("this.originData:", this.originData);
// 3 把接口的值存在list 里面
list.map(v => {
this.originData.map(item => {
if (v.broadcastinfoType === item.broadcastinfoType && v.priorityType === item.priorityType) {
v.level = item.level
}
})
})
})
.catch(error => {});
// 4 发送请求给后台 把list 传过去 调保存接口
this.editAll.priorityInfoList = list;
this.$axios({
// 修改优先级信息
method: "post",
data: this.editAll,
headers: { "Content-Type": "application/json" },
url: this.baseURL + "/priority/PriorityInfo/update_Priority "
})
.then(res => {
// console.log("000000:",res.data);
})
.catch(error => {});
// 5 重新调查询接口
this.search_all();
},
// 鼠标移入移出事件
// visible:function(){
// this.seen = true;
// },
// invisible:function(){
// this.seen = false;
// },
// 查询所有
search_all() {
this.$axios({
method: "get",
url: this.baseURL + "/priority/PriorityInfo/list_All",
})
.then(res => {
console.log("查询所有1:", res);
this.editAll.priorityInfoList = res.data; // 用于存放tab 里面的默认的初始值
})
.catch(error => {});
},
//保存- 修改
handleSave() {
// 那你就根据你修改过的数 来修改原本的数
// 然后把原本的数提交
console.log("this.record;", this.record, this.editAll.priorityInfoList); // 所有改变的值
this.editAll.priorityInfoList.map(v => {
this.record.map(item => {
if (v.broadcastinfoType === item.broadcastinfoType && v.priorityType === it