Vue动态扩展表头的表格及数据方式(数组嵌套对象)

实现效果

需求描述

接收后端传的json数据,数据格式为数组对象嵌套数组对象再嵌套对象,需要将每个数组对象遍历后取出想要的数据,通过forEach()方法来实现遍历、赋值。

数据结构

业务代码

<template>
 <div class="app-container">
 <!-- 表单区域 -->
 <el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px">
 <el-form-item label="店面" prop="storeId" label-width="40px">
 <treeselect v-model="queryParams.storeId" :options="deptOptions" :normalizer="normalizerDept" size="small"
 placeholder="请选择" class="treeselect-main" />
 </el-form-item>
 <el-form-item label="品牌" prop="brandId" label-width="40px">
 <el-select v-model="queryParams.brandId" filterable placeholder="请选择" clearable size="medium">
 <el-option v-for="dict in brandOptions" :key="dict.id" :label="dict.brand" :value="dict.id">
 </el-option>
 </el-select>
 </el-form-item>
 <el-form-item label="区域" prop="areaId" label-width="80px">
 <treeselect v-model="queryParams.areaId" :options="areaOptions" :normalizer="normalizer2" clearable size="small"
 placeholder="请选择" style="width:200px" />
 </el-form-item>
 <el-form-item label="日期" label-width="40px">
 <el-date-picker v-model="dateRange" size="small" style="width: 240px" value-format="yyyy-MM-dd" type="daterange"
 range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" :editable="false">
 </el-date-picker>
 </el-form-item>
 <el-form-item>
 <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
 <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
 <el-button type="warning" plain icon="el-icon-download" size="mini" :loading="exportLoading"
 @click="handleExport">导出</el-button>
 </el-form-item>
 </el-form>
 <!-- 表单区域结束 -->
 
 <!-- table表格区域 -->
 <el-table v-loading="loading" :data="mileageList" @selection-change="handleSelectionChange" border>
	 <el-table-column label="试驾车" align="center" :show-overflow-tooltip="true">
 <el-table-column label="店面" align="center" prop="storeName" :show-overflow-tooltip="true" width="180px" />
 <el-table-column label="总行驶次数" align="center" class-name="small-padding fixed-width" width="130">
 <template slot-scope="scope">
 <el-button size="mini" type="text" @click="handleInfo(scope.row,1, scope.row.totalMount)">
 {{ scope.row.totalMount }}
 </el-button>
 </template>
 </el-table-column>
 <el-table-column label="里程数(KM)" align="center" prop="totalMileage" width="130" :show-overflow-tooltip="true" />
 <el-table-column label="总时长(分钟)" align="center" prop="totalTime" width="130" :show-overflow-tooltip="true" />
 <el-table-column label="GPS预估数" align="center" prop="predictMileage" width="130" :show-overflow-tooltip="true" />
 <el-table-column label="里程占比" align="center" prop="mileageProportion" width="130" :show-overflow-tooltip="true" />
	 </el-table-column>
	
	 <el-table-column label="公务用车" align="center" :show-overflow-tooltip="true">
	<!--用车数据-->
	<el-table-column v-for="(planItem, index) in planList" :key="index" align="center" :label="planItem.dictLabel">
	 <el-table-column v-for="(stageItem, indexChild) in planItem.stageList" :key="index+'-'+indexChild" align="center"
	 :label="stageItem.stageLable" width="100">
	 <!-- <template slot-scope="scope">
	 <span>{{ scope.row.purposeTypeList[index].stageList[indexChild].value }}</span>
	 </template> -->
	<template slot-scope="scope">
	 <span v-if="scope.row.purposeTypeList[index].stageList[indexChild].stageLable == '行驶次数'">
	 <el-button size="mini" type="text" 
	 @click="handleInfo(scope.row,2, scope.row.month,planItem.stageList[indexChild].carType)">
	 {{ scope.row.purposeTypeList[index].stageList[indexChild].value }}
	 </el-button>
	 </span>
	 <span v-else>{{ scope.row.purposeTypeList[index].stageList[indexChild].value }}</span>
	</template>
	 </el-table-column>
	</el-table-column>
	 </el-table-column>
 </el-table>
 <!-- table表格区域结束 -->
 
 <!-- 分页区域 -->
 <pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
 @pagination="getList" />
 <!-- 分页区域结束 -->
 </div>
</template>
 
<script>
 import {
 selectMileageSumary,
 exportMileageSumary,
 exportDailyMileage
 } from "@/api/amtestdriver/drivecar";
 import Treeselect from "@riophae/vue-treeselect";
 import "@riophae/vue-treeselect/dist/vue-treeselect.css";
 import {
 selectDept
 } from "@/api/system/dept";
 import {
 listArea,
 } from "@/api/base/area/area";
 import {
 listData
 } from "@/api/base/carBrand/carBrand";
 export default {
 name: "Mileagereport",
 components: {
 Treeselect
 },
 data() {
 return {
 brandOptions: [], //品牌查询
 areaOptions: [], //区域
 deptOptions: [], //店面
	planList: [],//公务车数据
 dateRange: [],
 // 遮罩层
 loading: true,
 // 导出遮罩层
 exportLoading: false,
 // 选中数组
 ids: [],
 // 非单个禁用
 single: true,
 // 非多个禁用
 multiple: true,
 // 显示搜索条件
 showSearch: false,
 title: "",
 open: false,
 mileageList: [],
 // 总条数
 total: 0,
 // 查询参数
 queryParams: {
 pageNum: 1,
 pageSize: 10,
 storeId: null,
 brandId: null,
 areaId: null,
 }
 };
 },
 created() {
 this.getList();
 this.listDeptByType(2);
 listData(this.queryParams).then(response => {
 this.brandOptions = response.data;
 });
 listArea().then((response) => {
 this.areaOptions = this.handleTree(response.data, "id", "parentId");
 });
 },
 methods: {
 normalizer2(node) {
 if (node.children && !node.children.length) {
 delete node.children;
 }
 return {
 id: node.id,
 label: node.name,
 children: node.children,
 };
 },
 
 //加载店面列表
 listDeptByType(type) {
 this.queryParams.type = type;
 selectDept(this.queryParams).then(response => {
 this.deptOptions = this.handleTree(response.data, "deptId");
 if (response.data.length == 1) {
 this.queryParams.storeId = response.data[0].deptId;
 }
 });
 this.queryParams.type = null;
 },
 normalizerDept(node) {
 if (node.children && !node.children.length) {
 delete node.children;
 }
 return {
 id: node.deptId,
 label: node.deptName,
 children: node.children
 };
 },
 handleSelectionChange(selection) {
 this.ids = selection.map(item => item.id)
 this.single = selection.length !== 1
 this.multiple = !selection.length
 },
 handleQuery() {
 this.queryParams.pageNum = 1;
 this.getList();
 },
 getList() {
 this.loading = true;
 if (null != this.dateRange && this.dateRange.length > 0) {
 this.queryParams.startTime = this.dateRange[0];
 this.queryParams.endTime = this.dateRange[1];
 } else {
 this.queryParams.startTime = null;
 this.queryParams.endTime = null;
 }
 selectMileageSumary(this.queryParams).then(response => {
 this.mileageList = response.rows;
	 console.log(response.rows);
	 this.mileageList.forEach((res, index) => {
	 this.mileageList[index].purposeTypeList.forEach((re, aaa) => {
	 this.stageList=[];
	 if(this.mileageList[index].purposeTypeList[aaa].driveCarMileageSumary!=null){
	 this.stageList.push({stageLable: '行驶次数',value: this.mileageList[index].purposeTypeList[aaa].driveCarMileageSumary.officialMount,
	carType:this.mileageList[index].purposeTypeList[aaa].dictValue});
	 this.stageList.push({stageLable: '里程数(KM)',value: this.mileageList[index].purposeTypeList[aaa].driveCarMileageSumary.officialMileage});
	 this.stageList.push({stageLable: '时长(分钟)',value: this.mileageList[index].purposeTypeList[aaa].driveCarMileageSumary.officialTime});
	 this.stageList.push({stageLable: 'GPS预估数',value: this.mileageList[index].purposeTypeList[aaa].driveCarMileageSumary.officialPredictMileage});
	 this.stageList.push({stageLable: '里程占比',value: this.mileageList[index].purposeTypeList[aaa].driveCarMileageSumary.officialMileageProportion});
	 }else{
	 this.stageList.push({stageLable: '行驶次数',value: null,carType: null});
	 this.stageList.push({stageLable: '里程数(KM)',value: null});
	 this.stageList.push({stageLable: '时长(分钟)',value: null});
	 this.stageList.push({stageLable: 'GPS预估数',value: null});
	 this.stageList.push({stageLable: '里程占比',value: null});
	 }
	 this.mileageList[index].purposeTypeList[aaa].stageList = this.stageList;
	 })
	 })
	 this.planList = (this.mileageList[0] && this.mileageList[0]['purposeTypeList']) || [];
 this.total = response.total;
 this.loading = false;
 });
 },
 // 详情跳转
 handleInfo(row, type, val, carType) {
 if (val != 0) {
 let seaParams = {};
 seaParams = this.queryParams;
 seaParams.storeId = row.storeId;
 seaParams.appType = String(type);
 seaParams.dateRange = this.dateRange;
	 seaParams.type = carType,
 this.$router.push({
 path: '/mileage-report/details',
 query: seaParams,
 })
	 // console.log("this.queryParams",this.queryParams);
 }
 },
 // 重置按钮
 resetQuery() {
 this.queryParams.startTime = []
 this.queryParams.endTime = []
 this.dateRange = [];
 this.resetForm("queryForm");
 this.handleQuery();
 },
 /** 导出按钮操作 */
 handleExport() {
 const queryParams = this.queryParams;
 this.$confirm("是否导出里程报表数据?", "警告", {
 confirmButtonText: "确定",
 cancelButtonText: "取消",
 type: "warning",
 })
 .then(() => {
 this.exportLoading = true;
 return exportMileageSumary(queryParams);
 })
 .then((response) => {
 // console.log(response)
 this.downloads(response);
 this.exportLoading = false;
 })
 },
 /**
 * 导出下载
 * @param {Object} response
 */
 downloads(response) { // 拿到数据以后 通过 new Blob对象 创建excel
 if (!response) {
 return
 }
 let time = this.getNowTime();
 let fileName = time + '里程报表数据.xls'
 const blob = new Blob([response], {
 type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8'
 })
 // const blob = new Blob(["\ufeff",response], {type: 'text/plain'});
 const href = window.URL.createObjectURL(blob)
 const downloadElement = document.createElement('a')
 downloadElement.style.display = 'none'
 downloadElement.href = href
 downloadElement.download = fileName
 document.body.appendChild(downloadElement)
 downloadElement.click()
 document.body.removeChild(downloadElement) // 下载完成移除元素
 window.URL.revokeObjectURL(href) // 释放掉blob对象
 },
 // 获取当前时间
 getNowTime() {
 var nowDate = new Date();
 var year = nowDate.getFullYear();
 var month = nowDate.getMonth() + 1 < 10 ? "0" + (nowDate.getMonth() + 1) : nowDate.getMonth() + 1;
 var day = nowDate.getDate() < 10 ? "0" + nowDate.getDate() : nowDate.getDate();
 var dateStr = year + "" + month + "" + day;
 return dateStr;
 },
 
 }
 };
</script>
<style>
 .header {
 padding: 20px;
 margin-bottom: 10px;
 border-bottom: 1px solid #e6ebf5;
 }
</style>

总结

作者:半度纳原文地址:https://blog.csdn.net/Five297/article/details/127978018

%s 个评论

要回复文章请先登录注册