首先我本地先创建一个data.json文件 数据格式为
[
{
"name":"成品",
"parentCode":"0",
"code":"1",
"level":"0",
"children":[
{
"name":"材料1",
"parentCode":"1",
"code":"1-1",
"level":"1",
"children":[
{
"name":"材料11",
"parentCode":"1-1",
"code":"1-1-1",
"level":"2",
"children":[]
}
]
},
{
"name":"材料2",
"parentCode":"1",
"code":"1-2",
"level":"1",
"children":[]
}
]
}
]
此时的数据是没有时间的一个树形结构,然后我们初始化时间区间 为当天和前31天(注意:索引减30)
我用的elementUi时间插件
dateTime: [
new Date(new Date().getTime() - 30 * 24 * 60 * 60 * 1000),new Date(Date.now())
],//当前时间和过去31天的
首先先将时间区间转化成数组; 如 start: 2020-12-26 end 2020-11-26
let dateArr = this.getTimeArr(this.dateTime[0].Format('yyyy-MM-dd'),this.dateTime[1].Format('yyyy-MM-dd'),'yyyy-MM-dd',1);
然后遍历树形结构 将每天的时间 和价格 mock上去 字段为"priceInfo"
(可以递归遍历 也可以 将树形结构转化普通json数组遍历再转化树形 第二种比较麻烦 反正还原一下后台返回的数据 所以我的第二种)
let newData = this.treeTransArray(JSONDATA,'children');//JSONDATA就是data.json里的数据 这一步是将树形结构扁平化
newData.map(item=>{
item.priceInfo = dateArr.map(ele=>{//遍历时间数组
return {date:ele,price:Math.random()*10+2}
});//mock 数据
return item
});
let treeData = this.arrayTransTree(newData,'code','parentCode','children');//将扁平化的数组 在转化树形结构
拿到mock的数据格式为
未展开:
展开:
可以看到每个对象都有个priceInfo数组 里面是后台传来的时间区间和价格
然后需要根据时间段把时间数据提出来;
注释写到代码里的 直接放代码了
template
<template>
<div class="menus-tree">
<div class="search">
<el-date-picker
class="datePicker"
v-model="dateTime"
type="daterange"
range-separator="至"
:picker-options="pickerOptions"
start-placeholder="开始日期"
end-placeholder="结束日期"
>
</el-date-picker>
<el-button @click="initData()" style="float: right"
>查询</el-button>
</div>
<el-table
:data="tableData"
row-key="code"
:header-cell-style="headerStyle"
:cell-style="cellStyle"
default-expand-all
class="table-striped el-table"
:tree-props="{children: 'children', hasChildren: 'hasChildren'}"
max-height="350"
>
<template
v-for="(item,index) in tableColumn"
>
<!-- index是固定的字段个数 -->
<el-table-column
v-if="index<3"
fixed
:prop="item.props"
:key="index"
:width="item.width"
:label="item.label"
>
</el-table-column>
<el-table-column
v-else
:prop="item.props"
:key="index"
:min-width="item.width"
:label="item.label"
>
</el-table-column>
</template>
</el-table>
</div>
</template>
script
<script>
import Vue from 'vue';
import './format.js'
import JSONDATA from "./data.json";
export default {
data() {
return {
lineStyle: {
"font-size": "14px",
height: "45px",
padding: "3px 0",
},
pickerOptions: {//限制当前时间
disabledDate(time) {
return time.getTime() > Date.now();
},
},
dateTime: [
new Date(new Date().getTime() - 30 * 24 * 60 * 60 * 1000),new Date(Date.now())
],//当前时间和过去31天的
tableColumn:[],//表格列表
tableData:[],//表格数据
}
},
created() {
this.initData();//初始化数据 实际项目咋请求之后操作
},
methods: {
headerStyle() {
return this.lineStyle;
},
cellStyle() {
return this.lineStyle;
},
initData(){
//这里时间格式化 可以用vue的moment插件 看你个人
let dateArr = this.getTimeArr(this.dateTime[0].Format('yyyy-MM-dd'),this.dateTime[1].Format('yyyy-MM-dd'),'yyyy-MM-dd',1);
//-------start: 这里模拟后台数据格式 -------
let newData = this.treeTransArray(JSONDATA,'children');
newData.map(item=>{
item.priceInfo = dateArr.map(ele=>{
return {date:ele,price:Math.random()*10+2}
});
return item
});
let treeData = this.arrayTransTree(newData,'code','parentCode','children');
//-------end: 这里模拟后台数据格式 treeData 是树形结构 newData是普通结构 ------
//这里我直接拿第一个数据遍历组出表格列表
let columnArr = [];
for(var k in treeData[0]){
switch(k){
case 'level':
columnArr.push({props:k,label:'层级',width:120});
break;
case 'code':
columnArr.push({props:k,label:'编码',width:120});
break;
case 'name':
columnArr.push({props:k,label:'名称',width:120});
break;
case 'priceInfo':
treeData[0][k].forEach(item=>{
columnArr.push({'props':item.date,'label':item.date.slice(5),width:100});
});
break;
}
}
this.tableColumn = columnArr;
//------start: 将时间字段为key 价格为vule的对象处理出来放在 普通对象的字段里 ------
//1:处理表格数据 把每项时间对应的价格 和其他需要展示的字段提出来
let tableData = newData.map((item)=>{
let arr = [],obj;
item.priceInfo.forEach((ele,j)=>{
obj = {};
obj.date = ele.date;
obj.price = ele.price;
obj.level = item.level;
obj.name = item.name;
obj.parentCode = item.parentCode;
obj.code = item.code;
obj.children = [];//这里子项 我没用到 直接赋值空
arr.push(obj)
})
return arr
});
console.log('tableData',tableData)
//2:通过对象合并 处理成想要的格式
let newtableData = tableData.map((item) => {
let obj2 = {},arr2 = [];
item.forEach((ele) => {
obj2.level = ele.level;
obj2.parentCode = ele.parentCode;
obj2.name = ele.name;
obj2.code = ele.code;
obj2.children = ele.children;
obj2[ele.date] = ele.price; //价格
arr2.push(obj2);
});
return Object.assign.apply({}, arr2);
});
//------end: 将时间字段为key 价格为vule的对象处理出来放在 普通对象的字段里 ------
console.log('newtableData',newtableData)
//再将普通json 转化成树形 往组件里一丢 完事
this.tableData = this.arrayTransTree(newtableData,'code','parentCode','children');
},
getTimeArr(begin,end,type,interval){ //获取两个时间相邻的数组
var arr=[],beginDate,endDate,msCount;
beginDate=new Date(begin+" 00:00");
endDate=new Date(end+" 00:00");
msCount=interval*24*60*60*1000; //1天 2天 3天
var beginMs=beginDate.getTime();
var endMs=endDate.getTime();
for(var i=beginMs;i<=endMs;i+=msCount){
arr.push(new Date(i).Format(type));
}
return arr;
},
treeTransArray(tree, key) {//树转普通
return tree.reduce(function a(con, item) {
con.push(item);
if (item[key] && item[key].length > 0)
item[key].reduce(a, con);
return con;
}, [])
.map(function (item) {
item[key] = [];
return item;
});
},
arrayTransTree(list,idstr,pidstr,children){ //普通转树
let result = [],temp = {};
for(let i = 0; i < list.length; i++){
temp[list[i][idstr]]=list[i];//将nodes数组转成对象类型
}
for(let j=0; j<list.length; j++){
let tempVp = temp[list[j][pidstr]]; //获取每一个子对象的父对象
if(tempVp){//判断父对象是否存在,如果不存在直接将对象放到第一层
if(!tempVp[children]) tempVp[children] = [];//如果父元素的nodes对象不存在,则创建数组
tempVp[children].push(list[j]);//将本对象压入父对象的nodes数组
}else{
result.push(list[j]);//将不存在父对象的对象直接放入一级目录
}
}
return result;
},
}
}
</script>
style
<style scoped>
.search{
margin-bottom: 20px;
}
</style>
需要的format.js
export default Date.prototype.Format = function(fmt)//日期格式
{
var o = {
"M+" : this.getMonth()+1, //月份
"d+" : this.getDate(), //日
"h+" : this.getHours(), //小时
"m+" : this.getMinutes(), //分
"s+" : this.getSeconds(), //秒
"q+" : Math.floor((this.getMonth()+3)/3), //季度
"S" : this.getMilliseconds() //毫秒
};
if(/(y+)/.test(fmt)) {
fmt=fmt.replace(RegExp.$1, (this.getFullYear()+"").substr(4 - RegExp.$1.length));
}
for(var k in o) {
if(new RegExp("("+ k +")").test(fmt)) {
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length)));
}
}
return fmt;
};
实际效果展示
11-19 -> 12-28
12-24 -> 12-28
OK 就这样了 有问题可以私信我