前端深拷贝与浅拷贝
业务场景
小编是基于Vite+vue3 setup语法糖+TypeScripts开发
在开发过程中需要完成一个上下布局的数据可视化页面,大概就是下面图表无缝滚动点击后在上面渲染详情数据,下面的每个图只显示前五名,出于性能考虑目前数据量在可控范围内所以在调用该接口时直接全部返回,点击后我来渲染详情图表的逻辑所以就用到了‘splice’方法…
大概就是这个样子
首先封装组件
因为考虑到底部的图表都是一样的,所以封装一个组件方便维护。
父组件
<sortie-rank
:echartsOptions="sortieEchartsOptions"
@handleRankThanData="handleRankThanData"
ref="refSortieRank"
></sortie-rank>
子组件
<template>
<div class="sortieBack">
<!-- 列表 -->
<vue3ScrollSeamless
class="scroll-wrap"
:classOptions="classOptions"
:dataList="sortieEchartsOptions"
>
<ul class="ui-wrap">
<li
class="li-item"
ref="liItem"
v-for="(item, i) of sortieEchartsOptions"
:key="i"
@click="handleRankThanData1(item, i)"
>
<p>加载中...</p>
</li>
</ul>
</vue3ScrollSeamless>
</div>
</template>
因为需要无缝滚动用到了vue3-scroll-seamless插件
获取数据
目前六个图表 后端写了4个接口,所以使用了axios.all统一请求
// 使用Promise.all()等待所有请求完成
const result = await Promise.all(requestList);
resultList.value = result;
当写到这里的时候获取到的是20多个数据,但是当我在图表中使用是只需要显示5条 所以使用的splice截取了一下
data: echartsOptions.max?.splice(0, 5),
由于考虑到会操作原始数组所以拷贝了一份
sortieEchartsOptionsOptions.value = Array.from(sortieEchartsOptions1);
觉得一切很顺利,视图层也正常渲染了,当我想在点击时给附件传递数据改变详情页面时 发现了问题,不管怎么点击我获取到的数据都是我初始化时定义的原始数据,我排查了好多地方都无法解决
包括一个一个请求数据、动态监听数据变化等
// 获取数据
const getList1 = async () => {
// 使用Promise.all()等待所有请求完成
const result = await Promise.all(requestList);
resultList.value = result;
console.log("result===");
console.log(result);
console.log(sortieEchartsOptions);
console.log("result===");
await dataClick(result);
// 给详情页组件
refrankDetails.value.handleClztEcharts(result2.data);
};
// 获取数据
const getList2 = async () => {
let result: any = await xfjgjbxxSmallstation();
console.log("getList2===");
console.log(result);
resultList.value.splice(1, 0, result);
sortieEchartsOptions.value[1].max = result.data[1].max;
sortieEchartsOptions.value[1].value = result.data[1].value;
sortieEchartsOptions.value[1].name = result.data[1].name;
sortieEchartsOptions.value[2].max = result.data[2].max;
sortieEchartsOptions.value[2].value = result.data[2].value;
sortieEchartsOptions.value[2].name = result.data[2].value;
// refSortieRank.value.getEchartsDom();
// dataClick(result);
};
// 获取数据
const getList3 = async () => {
let result: any = await xfjgjbxxAllarrivetime();
console.log("getList3======");
console.log(result);
resultList.value.splice(2, 0, result);
sortieEchartsOptions.value[3].max = result.data.max;
sortieEchartsOptions.value[3].value = result.data.value;
sortieEchartsOptions.value[3].name = result.data.name;
// refSortieRank.value.getEchartsDom();
// dataClick(result);
};
// 获取数据
const getList4 = async () => {
let result: any = await xfjgjbxxArrivetimeranking();
console.log("getList4======");
console.log(result);
resultList.value.splice(3, 0, result);
sortieEchartsOptions.value[4].max = result.data[1].max;
sortieEchartsOptions.value[4].value = result.data[1].value;
sortieEchartsOptions.value[4].name = result.data[1].name;
sortieEchartsOptions.value[5].max = result.data[2].max;
sortieEchartsOptions.value[5].value = result.data[2].value;
sortieEchartsOptions.value[5].name = result.data[2].name;
// refSortieRank.value.getEchartsDom();
// dataClick(result);
};
watch(sortieEchartsOptions.value, (newValue) => {
console.log("newValue====");
console.log(newValue);
if (
newValue[0].max.length > 1 &&
newValue[1].max.length > 1 &&
newValue[2].max.length > 1 &&
newValue[3].max.length > 1 &&
newValue[4].max.length > 1 &&
newValue[5].max.length > 1
) {
resultList.value = newValue;
refSortieRank.value.getEchartsDom();
}
});
发现都没效果 没办法了 只能一个一个地方打桩,一个一个地方注释,发现不调用Echarts图表就没事,我就很纳闷不应该啊,然后我在该方法中发现我的原始值因为splice的原因改变了地址所以我的数据没了,可是我明明已经拷贝了啊,但是在浏览器试一下发现确实这种多元结构的数组用es6的解构赋值和Array.from都是不起作用的,最后选择了用转Json的方式完美解决以下是我的测试过程
丢人…