注意:我这里是当下不超过600个标记点,所以我这里是一次性渲染出来进行优化的,如果数据大于2000条甚至更大的时候,需要用其他的优化方法,而不是这样一次性全部渲染出来这些所有标记点的数据。
需求: 在首页的地图内,增加一个一个的marker来进行展示echarts,效果如下图,地图用的是leaflet,图表用的是echarts
在开发中,我遇到两个比较大的问题
第一个:
图表一直加载的问题,因为当我点击不同的图表时会显示不同的图表详情,那我地图上的所有图表都再次进行循环渲染,然后实现页面完整的展示,可这样做,用户等待的时间过久,体验优化做的不好,所以我这里在组件内使用了useMemo来实现了标签只执行一次的设置,然后监听用户搜索后数据的更改后再进行重新的页面渲染。
代码仅供展示:
<Card className={style.home_mapCom}>
<MapContainer
crs={CRS_4490}
zoomSnap={0.1}
center={posiPoint}
zoom={zoomData}
layers={[TiledMapLayer]}
scrollWheelZoom={true}
style={{ heihgt: 'auto', backgroundColor: '#fff' }}
>
{useMemo(
() => (
<>
{mapData.length > 0 &&
mapData.map((item) => {
return (
<>
<Marker
key={item.companyId}
position={item.point}
icon={LeafIcon3(item)}
eventHandlers={{
click: () => MarkerEventClick(item),
}}
/>
</>
);
})}
</>
),
[mapData],
)}
<MyComponent />
<MarkPosition showView={markShow} />
</MapContainer>
{/* 详情展示部分 */}
{isEndShow()}
</Card>
第二个:
但是这样做还会有一次问题 页面的图表渲染是根据js获取标签id来进行渲染的,当我useMemo获取到数据进行渲染了,而我的图表已经开始渲染了,这样会造成页面并未展示出来我的图表,仅是展示出来我的标签。那这里我用useEffect来解决的
// 顺序 1
useEffect(() => {
setPosiPoint([...position]);
setZoomData(props.zoom);
setClose('none');
}, []);
// 顺序 2
useEffect(() => {
setMapData(mapList || []);
if (mapList && mapList.length) {
setZoomData(props.zoom);
setMapData(mapList || []);
} else {
setZoomData(10.5);
setMapData([]);
}
}, [posiPoint, mapList]);
// 顺序 3 —— 这里主要是用来监听mapData获取了新的数据后,重新渲染echarts图的
useEffect(() => {
getEchartsOption();
if (JSON.stringify(mapList) === '[]') {
setClose('noEnd');
} else if (mapData && mapData.length > 0) {
setClose('none');
}
setMarkShow(false);
setZoomData(10.5);
}, [mapList, mapData]);
总结:这里的优化告诉我,使用哪个框架就要把那个框架内的api和官网了解清楚,这也是为了我们更好地在做项目中针对组件做优化。