進入到尾聲,範例的最後一片拼圖,馬上開始吧!!!
地圖的部分使用了leaflet JS和OpenStreetMap,所以在開始前先裝一下leaflet,在終端機打上
npm install leaflet
完成後,接下來和先前的步驟一樣,先在components下建立一個maskMap.vue,把App.vue的地圖部分搬過來
<template>
<div class="mask-map" id="mask-map"></div>
</template>
<script>
export default {
name: "maskMap",
};
</script>
再來修改App.vue
<template>
<div id="app">
<!-- aside-menu 左側欄 -->
<asideMenu />
<!-- 地圖區塊 -->
<maskMap />
<!-- lightBox -->
<light-box />
</div>
</template>
<script>
import { mapActions } from "vuex";
import asideMenu from "./components/asideMenu.vue";
import lightBox from "./components/lightBox.vue";
import maskMap from "./components/maskMap.vue";
export default {
name: "App",
components: {
asideMenu,
lightBox,
maskMap,
},
//...略
};
</script>
回到maskMap.vue將leaflet弄進來
import L from "leaflet";
export default {
name: "maskMap",
data() {
return {
//別的地方用不到map,所以不用丟到vuex
map: {},
};
},
mounted() {
//初始化地圖
this.map = L.map("mask-map", {
center: [25.03, 121.55],
zoom: 14,
});
L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
attribution:
'<a target="_blank" href="https://www.openstreetmap.org/">OpenStreetMap貢獻者</a>',
maxZoom: 18,
}).addTo(this.map);
},
};
完成後可以看到完整地圖的畫面
有了地圖後就要讓他和右邊的縣市行政區去做反應,選擇哪個區域就要到對應的地圖區塊,只要從vuex拿state.currCity和getters.districtList做比對就可以完成,先在getters加上:
currDistrictInfo(state, getters) {
// 目前所選行政區
return getters.districtList.find((d) => d.name === state.currDistrict) || {}
}
也在maskMap.vue加上computed,把getter拿回
computed: {
currDistrictInfo() {
return this.$state.getters.currDistrictInfo;
},
},
並在此加上watch,當使用者切換行政區地圖也會跟著移動
watch: {
currDistrictInfo(dist) {
//this.map.panTo可以指定地圖中心點
this.map.panTo(new L.LatLng(dist.latitude, dist.longitude));
},
},
藥局的資料在剛剛已經有從vuex拿到手了,再來就是在maskMap.vue加入computed
filteredStores() {
return this.$store.getters.filteredStores;
},
還有在watch身上新增filteredStores,列表變動透過addMarker來增加圖釘
filteredStores(stores) {
stores.forEach((element) => this.addMarker(element));
},
再來就是在methods定義剛剛的addMarker
addMarker(item) {
//標記圖案
const ICON = {
iconUrl:
"https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-violet.png",
shadowUrl:
"https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/images/marker-shadow.png",
iconSize: [25, 41],
iconAnchor: [12, 41],
popupAnchor: [1, -34],
shadowSize: [41, 41],
};
//將標記放到地圖上
const marker = L.marker([item.longitude, item.latitude], ICON)
.addTo(this.map)
.bindPopup(`<h2 class="popup-name">${item.name}</h2>`);
},
當多次切換行政區時標記的點並不會清除,反而是累加上去的,所以在methods上要加上clearMarker來清除
clearMarkers() {
//清除地圖所有標記
this.map.eachLayer((layer) => {
if (layer instanceof L.Marker) {
this.map.removeLayer(layer);
}
});
},
並改寫一下watch中的filteredStores
filteredStores(stores) {
//先清除原有marker
this.clearMarkers();
//根據藥局資訊加上對應的marker
stores.forEach((element) => this.addMarker(element));
},
就差一點點了!! 今天來不及弄完,明天再續