面试题答案
一键面试设计思路
- 分离关注点:将地图相关的操作(如添加标记点、处理点击事件)与Svelte的状态管理分开。利用Svelte的响应式系统来管理应用的状态,如标记点数据、当前显示的详细信息等。
- 单向数据流:确保数据从父组件流向子组件,减少不必要的状态共享。标记点数据作为属性传递给地图组件,地图组件通过事件通知父组件更新状态。
- 事件委托:在地图上使用事件委托来处理标记点的点击事件,而不是为每个标记点单独绑定事件,减少事件处理程序的数量,提高性能。
- 优化重渲染:利用Svelte的
$:
语句和derived
函数来精确控制状态变化导致的重渲染。只在必要时更新DOM,避免不必要的重渲染。
关键实现步骤
- 初始化地图:在Svelte组件的
onMount
生命周期钩子中初始化Leaflet地图,并将其存储在组件的变量中。 - 添加标记点:根据从父组件传递过来的标记点数据,使用Leaflet的API添加标记点到地图上。可以使用事件委托来处理标记点的点击事件。
- 处理点击事件:当标记点被点击时,通过Svelte的
dispatch
方法触发一个自定义事件,将标记点的数据传递给父组件。父组件接收到事件后,更新状态以显示详细信息框。 - 更新标记点:当标记点的位置、数量等信息发生变化时,通过更新Svelte组件的状态,重新渲染地图组件,从而更新地图上的标记点。
核心代码示例
<script>
import { onMount } from'svelte';
import L from 'leaflet';
let map;
let markers = [];
let currentMarkerData;
const markerData = [
{ lat: 51.505, lng: -0.09, info: 'Marker 1 Info' },
{ lat: 51.51, lng: -0.1, info: 'Marker 2 Info' }
];
onMount(() => {
map = L.map('map').setView([51.505, -0.09], 13);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
}).addTo(map);
function addMarkers() {
markers.forEach(marker => map.removeLayer(marker));
markers = markerData.map(data => {
const marker = L.marker([data.lat, data.lng]);
marker.on('click', () => {
currentMarkerData = data;
const detail = { data };
const event = new CustomEvent('marker-click', { detail });
document.dispatchEvent(event);
});
marker.addTo(map);
return marker;
});
}
addMarkers();
document.addEventListener('marker-update', () => {
addMarkers();
});
return () => {
markers.forEach(marker => map.removeLayer(marker));
map.remove();
};
});
</script>
<div id="map" style="height: 400px;"></div>
{#if currentMarkerData}
<div class="info-box">
<p>{currentMarkerData.info}</p>
</div>
{/if}
<style>
.info-box {
position: absolute;
top: 10px;
left: 10px;
background-color: white;
padding: 10px;
border: 1px solid gray;
border-radius: 5px;
}
</style>
上述代码展示了如何在Svelte中集成Leaflet地图,并实现标记点的交互和状态管理。markerData
数组模拟了从后端获取或用户操作更新的标记点数据。通过addMarkers
函数,每次数据更新时,先移除旧的标记点,再添加新的标记点。点击标记点时,通过自定义事件marker-click
通知父组件更新currentMarkerData
状态,从而显示详细信息框。marker-update
事件用于在数据更新时重新渲染地图上的标记点。