周菜谱需求,在VUE里处理表格及做数据转换
本文为 正闲 原创文章,如需转载需得到本人授权
最终效果
项目背景
最近在处理一个基于微信公众号的内部订餐项目,技术是Java(Spring Boot)+VUE(uni-app),其中有一个需求是要做周菜谱,后端下发的数据格式如下:
// 后端发送的消息JSON格式如下:
{
"code": 0,
"msg": "",
"data": {
"listofDay": [
{
"week": 1,
"dayDate": "2020-03-30",
"listofFood": []
},
{
"week": 2,
"dayDate": "2020-03-31",
"listofFood": []
},
{
"week": 3,
"dayDate": "2020-04-01",
"listofFood": []
},
{
"week": 4,
"dayDate": "2020-04-02",
"listofFood": []
},
{
"week": 5,
"dayDate": "2020-04-03",
"listofFood": [
{
"id": 1,
"period": 1,
"food_name": "米饭",
"price": "0.01"
}
]
},
{
"week": 6,
"dayDate": "2020-04-04",
"listofFood": [
{
"id": 1,
"period": 1,
"food_name": "米饭",
"price": "0.01"
}
]
},
{
"week": 7,
"dayDate": "2020-04-05",
"listofFood": [
{
"id": 1,
"period": 0,
"food_name": "米饭",
"price": "0.01"
}
]
}
]
}
}
关于VUE的表格处理
VUE element-UI 表格处理的 API 参考地址:
https://element.eleme.io/2.0/#/zh-CN/component/table
访问
任务目标
1.显示表格,多级表头、星期(week)转为中文显示。
2.按照时段(period)字段转为中文,并排序。
3.消息格式转换。
4.时段合并单元格(还未实现,可结合API自行研究解决)。
主要代码
// 主要代码
<template>
<div class="orderList">
<div class="api_right_tit">
<div class="date_block">
<span>日期:</span>
<el-date-picker
v-model="updateDate"
type="date"
@change="dateChange"
format="yyyy 年 MM 月 dd 日"
value-format="yyyy-MM-dd"
placeholder="选择日期"
></el-date-picker>
</div>
</div>
<!-- 由 tableDate.length 决定数据表格的高度(固定为5)实际数据是用 listofDay -->
<el-table :data="tableDate" stripe ref="multipleTable"
:header-cell-style="funTableHeaderStyle"
:cell-style="funTableCellStyle"
>
<el-table-column prop="period" label="时段" width="55" :formatter="funFormatPeriod"></el-table-column>
<!-- 2020-04-20 周一 由 tableHeaderInfo.length 决定数据表格的宽度-->
<el-table-column v-for="(headItem, headIndex) in tableHeaderInfo" v-bind:key="headItem.id" :label="headItem.dayDate">
<el-table-column :prop="'day'+(headIndex+1)+'.name'" :label="headItem.week" :render-header="funRenderHeaderWeek">
</el-table-column>
<el-table-column :prop="'day'+(headIndex+1)+'.price'" label="单价" width="50">
</el-table-column>
</el-table-column>
</el-table>
</div>
</template>
<script>
export default {
data() {
return {
//查询数据
updateDate: '',
isRun: false,
//表格基本信息(从listofDay中抽离出来)
tableHeaderInfo:[{
dayDate:'2020-04-28',
week:'1'
}, {
dayDate:'2020-04-21',
week:'2'
}, {
dayDate:'2020-04-22',
week:'3'
},{
dayDate:'2020-04-23',
week:'4'
},{
dayDate:'2020-04-24',
week:'5'
},{
dayDate:'2020-04-25',
week:'6'
},{
dayDate:'2020-04-26',
week:'7'
}],
//表示正式数据(数据长度即,表格高度)(需转译,时段信息(包含5个时段))
tableDate:[{
period:0,
day1:{name:'',price:''},
day2:{name:'',price:''},
day3:{name:'',price:''},
day4:{name:'',price:''},
day5:{name:'',price:''},
day6:{name:'',price:''},
day7:{name:'',price:''}
}]
}
},
mounted() {
},
created() {
//初始化月数据
this.getMonDate();
//初始化
this.getData();
},
methods: {
//表头样式
funTableHeaderStyle:function(row, column, rowIndex, columnIndex){
return {'font-size': '12px','padding':'6px 0px 6px 0px','text-align':'center','background-color': '#FFFFFF'};
},
//表格内容样式
funTableCellStyle:function(row, column, rowIndex, columnIndex){
return {'font-size': '10px','padding':'2px 0px 2px 0px','text-align':'center'};
},
// 取餐日期改变后重新获取菜品分类列表和菜品列表
dateChange(dateText) {
//console.log("查询数据发生变化");
// console.log("dateText = "+dateText);
//数据容错处理
if (!dateText) return '';
if (dateText.length>0){
//数据大于0才处理,屏蔽清空后的无效消息
this.getData();
}
},
//与服务器通讯
getData() {
let postObj = {
keyDate: this.updateDate
};
var WeekList = [];
this.$axios.post("getWeekPlanTable", postObj).then(res => {
if (res.code == 0) {
console.log("数据获取成功!");
WeekList = res.data.listofDay;
//console.log("WeekList = "+WeekList);
//(Done)更新表头数据
let fTableHeaderInfo = JSON.parse(JSON.stringify(WeekList));
//刷新头信息 包含日期和星期
this.refreshHeaderInfo(fTableHeaderInfo);
//刷新表数据信息 包含时段 、菜品 和 价格
this.refreshFoodInfo(fTableHeaderInfo);
//console.log("this.tableHeaderInfo = "+JSON.stringify(this.tableHeaderInfo));
} else {
console.log("服务器提示错误!");
this.$message({
type: "info",
message: res.msg
});
}
});
},
//(核心关键)刷新表数据信息 包含时段 、菜品 和 价格
refreshFoodInfo:function(objHeader){
//各时段上限(赋值到全局变量中可供合并单元格使用)
let fPeriodSize = [0,0,0,0,0];
//每天的中间数据(内部包含这一天内各时段数据size7,各时段数据是数组)使用Map方便排序
let fMapTableDate = new Map();
//初始化食品数据
if (objHeader.length>0){
this.tableDate=[];
}
for (var i = 0; i < objHeader.length; i++) {
//新建二维map存储子数据
fMapTableDate.set(i,new Map());
let fArrFoodListByOneDay = objHeader[i]['listofFood'];
//console.log("i = "+i+" fArrFoodListByOneDay.length = "+fArrFoodListByOneDay.length);
for (var j = 0; j < fArrFoodListByOneDay.length; j++) {
let fAFood = fArrFoodListByOneDay[j];
let fPeriod = fAFood['period'];
//console.log("fPeriod = "+fPeriod);
//构建 及 序列化 各时段对象
if (!fMapTableDate.get(i).has(fPeriod)){
//初始化某时段数组
fMapTableDate.get(i).set(fPeriod,[]);
}
//添加食物对象
fMapTableDate.get(i).get(fPeriod).push(fAFood);
//=== Begin 尝试更新本时段最大值计数器
let nowNum = fMapTableDate.get(i).get(fPeriod).length;
// console.log("nowNum = "+nowNum);
let maybeMaxNum = fPeriodSize[fPeriod];
// console.log("maybeMaxNum = "+maybeMaxNum);
if (nowNum>maybeMaxNum){
// console.log(">>>>>> set values");
fPeriodSize[fPeriod] = nowNum;
}
// console.log("update fPeriodSize[fPeriod] = "+fPeriodSize[fPeriod]);
//=== End 尝试更新本时段最大值计数器
//console.log("i = "+i+" j= "+j+" obj = "+JSON.stringify(fAFood));
}
}
console.log("fMapTableDate.size = "+fMapTableDate.size);
console.log("fPeriodSize = "+fPeriodSize);
//补齐各时段空数据 m为时段
for (var m = 0; m < fPeriodSize.length; m++) {
//本时段最大值
let nowMax = fPeriodSize[m];
if (nowMax>0){
//从队列中拉取数据,并补齐数据
for (var n = 0; n < nowMax; n++) {
console.log("m = "+m);
//为了看得清楚 特意写清楚一条数据的结构
let fAFoodCell = {
period:m,
day1:{name:'',price:''},
day2:{name:'',price:''},
day3:{name:'',price:''},
day4:{name:'',price:''},
day5:{name:'',price:''},
day6:{name:'',price:''},
day7:{name:'',price:''}
};
//添加最终数据
//this.tableDate.push(fAFoodCell);
//fMapTableDate.size就是7
for (var p = 0; p < fMapTableDate.size; p++) {
//从队列判断队列是否为空
if (fMapTableDate.get(p).has(m)){
//console.log("p = "+p+" 存在时段 m = "+m);
//剩余数据
let remainFood = fMapTableDate.get(p).get(m).length;
//console.log("remainFood = "+remainFood);
if (remainFood>0){
//从队列中挤压出数据
let fOneFoodObj = fMapTableDate.get(p).get(m).shift();
let fNeedAddFood = {name:fOneFoodObj['food_name'],price:fOneFoodObj['price']};
console.log("needAddFood = "+JSON.stringify(fNeedAddFood));
//补齐对象
fAFoodCell['day'+(p+1)] = fNeedAddFood;
}else{
//补齐对象
fAFoodCell['day'+(p+1)]={name:'',price:''};
}
}else{
//补齐对象
fAFoodCell['day'+(p+1)]={name:'',price:''};
}
}
//添加最终数据
this.tableDate.push(fAFoodCell);
}
}
}
//TODO use fPeriodSize 赋值到全局变量中可供合并单元格使用
},
//刷新头信息 包含日期和星期
refreshHeaderInfo:function(objHeader){
//初始化表头数据
if (objHeader.length>0){
this.tableHeaderInfo=[];
}
//console.log("this.tableHeaderInfo = "+objHeader);
for (var i = 0; i < objHeader.length; i++) {
let fObj = objHeader[i];
// console.log("i = "+i+" obj = "+fObj);
// console.log("this.tableHeaderInfo = "+JSON.stringify(fObj));
//构造一个对象
//解决消息中 week Number转化为String 问题
let objItem = {dayDate:fObj['dayDate'],
week:String(fObj['week'])};
//插入对象
this.tableHeaderInfo.push(objItem);
}
},
//初始化 搜索框内容 默认显示第二天的日期
getMonDate() {
// const date = new Date();
// let day = date.getDate() + 1;
// const mondate = new Date(date.setDate(day));
// console.log(mondate);
const curDate = new Date();
var mondate = new Date(curDate.getTime()); //后一天
let year = mondate.getFullYear();
let month = mondate.getMonth() + 1;
let day = mondate.getDate();
month = month > 9 ? month : "0" + month;
day = day > 9 ? day : "0" + day;
this.updateDate = `${year}-${month}-${day}`;
},
//渲染 header 星期几
funRenderHeaderWeek:function(h,{column}){
var weekChar = "星期";
switch(column.label){
case '1':
weekChar = "星期一";
break;
case '2':
weekChar = "星期二";
break;
case '3':
weekChar = "星期三";
break;
case '4':
weekChar = "星期四";
break;
case '5':
weekChar = "星期五";
break;
case '6':
weekChar = "星期六";
break;
case '7':
weekChar = "星期天";
break;
default:
weekChar = "未知";
};
return h(
'div',
[
h('span', weekChar)
],
);
},
//渲染表头日期 2020-04-20, 2020-04-21 ... 等等
funRenderHeaderDate:function (h,{column}) {
return h(
'div',
[
h('span', column.label+"_"),
h('i', {
class:'el-icon-location',
style:'color:#409eff;margin-left:5px;'
})
],
);
},
//将时段(period)数字 转化为中文
funFormatPeriod:function(row, column, rowIndex, columnIndex){
//获取行数
//var fRowNum = columnIndex;
console.log('row.period = '+row.period);
//获取时段参数
switch(row.period){
case 0:
return '临时';
break;
case 1:
return '早餐';
break;
case 2:
return '午餐';
break;
case 3:
return '晚餐';
break;
case 4:
return '夜宵';
break;
default:
return '未知';
}
return '无效';
}
},
computed: {
showThis: function () {
if (this.isRun) {
// show chart
} else {
// hide chart
}
return this.isRun;
}
},
}
</script>
<style>
.cell_style {
text-align: center;
}
.all_style {
align-content: center;
}
.api_right_tit {
height: 60px;
width: 100%;
}
.date_block {
width: 350px;
margin-top: 5px;
float: left;
margin-left: 50px;
}
.date_block span {
margin-right: 20px;
}
</style>