我們在上一篇介紹到如何使用 Leaflet
與 OpenStreetMap
來製作地圖,不過上一篇是直接使用 CDN 的方式來做載入,而這篇我們會使用安裝的方式,並結合 Vue
來實作,那就開始吧~
這邊使用 Vue CLI
開啟一個新專案,接著下載 vue2-leaflet 這個套件
$ npm install vue2-leaflet leaflet --save
載入的部分官網寫得相當詳細,我們首先須載入 css
,再於全域載入組件,功能依照自己需求做選擇,可參考這裡,這邊順便提一下,如果 icon 無法正常顯示的話,官方這邊也提供了解決方法,我們也直接寫入設定
// main.js
import Vue from "vue";
import App from "./App.vue";
// 載入 vue2-leaflet,依照自己需要載入組件
import { LMap, LTileLayer, LMarker, LPopup, LIcon } from "vue2-leaflet";
// 載入 css
import "leaflet/dist/leaflet.css";
// 啟用載入的各組件
Vue.component("l-map", LMap);
Vue.component("l-tile-layer", LTileLayer);
Vue.component("l-marker", LMarker);
Vue.component("l-popup", LPopup);
Vue.component("l-icon", LIcon);
// 設定預設 icon
import { Icon } from "leaflet";
delete Icon.Default.prototype._getIconUrl;
Icon.Default.mergeOptions({
iconRetinaUrl: require("leaflet/dist/images/marker-icon-2x.png"),
iconUrl: require("leaflet/dist/images/marker-icon.png"),
shadowUrl: require("leaflet/dist/images/marker-shadow.png")
});
Vue.config.productionTip = false;
new Vue({
render: h => h(App)
}).$mount("#app");
為了比較好閱讀,這邊會把資料都在 APP.vue
這個檔案內,基本上就是把之前的功能都用 Vue
寫一次~
<template>
<div id="app">
<!-- 初始化地圖設定 -->
<l-map
ref="myMap"
:zoom="zoom"
:center="center"
:options="options"
style="height: 100vh;">
<!-- 載入圖資 -->
<l-tile-layer :url="url" :attribution="attribution" />
<!-- 自己所在位置 -->
<l-marker ref="location" :lat-lng="center">
<l-popup>
你的位置
</l-popup>
</l-marker>
<!-- 創建標記點 -->
<l-marker :lat-lng="item.local" v-for="item in data" :key="item.id">
<!-- 標記點樣式判斷 -->
<l-icon
:icon-url="item.name === '夢時代購物中心'?icon.type.gold:icon.type.black"
:shadow-url="icon.shadowUrl"
:icon-size="icon.iconSize"
:icon-anchor="icon.iconAnchor"
:popup-anchor="icon.popupAnchor"
:shadow-size="icon.shadowSize"
/>
<!-- 彈出視窗 -->
<l-popup>
{{ item.name }}
</l-popup>
</l-marker>
</l-map>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
// 模擬資料
data: [
{ id: 1, name: "夢時代購物中心", local: [22.595153, 120.306923] },
{ id: 2, name: "漢神百貨", local: [22.61942, 120.296386] },
{ id: 3, name: "漢神巨蛋", local: [22.669603, 120.302288] },
{ id: 4, name: "大統百貨", local: [22.630748, 120.318033] }
],
zoom: 13,
center: [22.612961, 120.304167],
url: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
attribution: `© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors`,
options: {
zoomControl: false
},
icon: {
type: {
black:
"https://cdn.rawgit.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-black.png",
gold:
"https://cdn.rawgit.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-gold.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]
}
};
},
mounted() {
// 等地圖創建後執行
this.$nextTick(() => {
// 獲得目前位置
navigator.geolocation.getCurrentPosition(position => {
const p = position.coords;
// 將中心點設為目前的位置
this.center = [p.latitude, p.longitude];
// 將目前的位置的標記點彈跳視窗打開
this.$refs.location.mapObject.openPopup();
});
});
}
};
</script>
<style>
html,body {
padding: 0;
margin: 0;
}
</style>
成果如下~
上次介紹 markercluster 這個插件,而他也有 vue2-leaflet-markercluster 這個 Vue
的版本,這次我們一樣把她加入 Demo 中,首先安裝套件
$ npm install vue2-leaflet-markercluster --save
接下來在剛剛的 Demo 中新增幾行程式碼來載入套件
// main.js
// 載入 css
import 'leaflet.markercluster/dist/MarkerCluster.css';
import 'leaflet.markercluster/dist/MarkerCluster.Default.css';
// 載入 markercluster 並啟用
import Vue2LeafletMarkerCluster from 'vue2-leaflet-markercluster';
Vue.component('v-marker-cluster', Vue2LeafletMarkerCluster);
最後再將載入的組件加在頁面上就完成囉
<!-- 加入組件 tag -->
<v-marker-cluster>
<l-marker :lat-lng="item.local" v-for="item in data" :key="item.id">
<l-icon
:icon-url="item.name === '夢時代購物中心' ? icon.type.gold : icon.type.black"
:shadow-url="icon.shadowUrl"
:icon-size="icon.iconSize"
:icon-anchor="icon.iconAnchor"
:popup-anchor="icon.popupAnchor"
:shadow-size="icon.shadowSize"
/>
<l-popup>{{ item.name }}</l-popup>
</l-marker>
</v-marker-cluster>
成果如下~
這次將上一篇的東西全部換成 vue 的組件,基本上只是將 js 內的設定改用 vue 的寫法寫在組件上,功能都是一樣,用法也相當容易,之後就交給大家試試囉!