在VUE里处理表格及做数据转换

周菜谱需求,在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>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值