我们在上一篇介绍到如何使用 Leaflet
与 OpenStreetMap
来製作地图,不过上一篇是直接使用 CDN 的方式来做载入,而这篇我们会使用安装的方式,并结合 Vue
来实作,那就开始吧~
安装
这边使用 Vue CLI
开启一个新专案,接着下载 vue2-leaflet 这个套件
$ npm install vue2-leaflet leaflet --save
载入的部分官网写得相当详细,我们首先须载入 css
,再于全域载入组件,功能依照自己需求做选择,可参考这里,这边顺便提一下,如果 icon 无法正常显示的话,官方这边也提供了解决方法,我们也直接写入设定
// main.jsimport Vue from "vue";import App from "./App.vue";// 载入 vue2-leaflet,依照自己需要载入组件import { LMap, LTileLayer, LMarker, LPopup, LIcon } from "vue2-leaflet";// 载入 cssimport "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);// 设定预设 iconimport { 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>
成果如下~
plugin
上次介绍 markercluster 这个插件,而他也有 vue2-leaflet-markercluster 这个 Vue
的版本,这次我们一样把她加入 Demo 中,首先安装套件
$ npm install vue2-leaflet-markercluster --save
接下来在刚刚的 Demo 中新增几行程式码来载入套件
// main.js// 载入 cssimport '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 的写法写在组件上,功能都是一样,用法也相当容易,之后就交给大家试试啰!