通过 Vue + 高德地图 JS API 在地图上标记咖啡店
在上一篇教程中我们为咖啡店地址进行了地理编码,这样,就可以调用高德地图支持的各种 API 来实现我们想要实现的功能(地图服务都是基于地理编码来实现),在这篇教程中,我们将基于地理编码在地图上标记咖啡店,我们将通过在 Cafes
页面中包含地图组件来实现这个功能。
第一步:获取高德地图 JS API Key
由于是在前端实现地图标记功能,所以需要申请高德地图的 JS API Key,在上一篇教程创建的应用中添加 Key,在弹出页面选择「Web端」即可:
创建完成后即可在应用 Key 列表中看到了。
第二步:将 API Key 添加到 config.js 中
和 Laravel 后端类似,接下来我们将上一步申请的 JS API Key 添加到前端配置文件 resources/assets/js/config.js
中,以便可以全局使用:
/**
* Defines the API route we are using.
*/
var api_url = '';
var gaode_maps_js_api_key = '{YOUR API KEY HERE}';
switch( process.env.NODE_ENV ){
case 'development':
api_url = 'http://roast.test/api/v1';
break;
case 'production':
api_url = 'http://roast.demo.laravelacademy.org/api/v1';
break;
}
export const ROAST_CONFIG = {
API_URL: api_url,
GAODE_MAPS_JS_API_KEY: gaode_maps_js_api_key
};
第三步:添加高德地图脚本到 app.blade.php
高德地图完整的 JS API 文档参考这里:https://lbs.amap.com/api/javascript-api/summary,可以翻阅下这篇文档快速了解 JS API 的使用以及提供的功能。在使用高德地图 JS API 之前,需要先在页面引入 JS API 的入口脚本,由于我们的应用是单页面应用,故而在 resources/views/app.blade.php
中引入即可,这样所有子页面都可以使用高德地图 JS API:
<script src="https://webapi.amap.com/maps?v=1.4.8&key=您申请的key值"></script>
这里为了简化代码逻辑,我们使用的是同步方式引入,你也可以通过异步方式引入,参考高德地图 API 文档即可。
第四步:新增 CafeMap 组件
我们将以 Vue 组件方式展示地图,以便可以插入到不同页面,从而方便复用和维护,为此,我们在 resources/assets/js/components
目录下创建一个 cafes
子目录,然后在该子目录下创建 CafeMap.vue
组件,并编写好组件代码结构:
<style lang="scss">
</style>
<template>
<div id="cafe-map">
</div>
</template>
<script>
export default {
}
</script>
第五步:添加高德地图到组件
然后我们在 CafeMap.vue
组件中初始化高德地图的绘制,首先来定义高德地图的一些必备属性:
props: {
'latitude': { // 经度
type: Number,
default: function () {
return 120.21
}
},
'longitude': { // 纬度
type: Number,
default: function () {
return 30.29
}
},
'zoom': { // 缩放级别
type: Number,
default: function () {
return 4
}
}
},
data() {
return {}
},
以 props
方式从父组件中传递属性数据的好处是方便在不同页面传入不同的属性值,从而提高组件的灵活性,如果你对上述语法不太了解,可参考 Vue 的组件文档。
其次定义高德地图显示样式:
<style lang="scss">
div#cafe-map {
width: 100%;
height: 400px;
}
</style>
最后定义高德地图初始化绘制脚本,我们将在 mounted()
方法中定义这段代码,以便每次页面载入时都会重新绘制地图:
mounted() {
this.map = new AMap.Map('cafe-map', {
center: [this.latitude, this.longitude],
zoom: this.zoom
});
}
在初始化绘制代码中,我们用到了从父组件传入的经纬度和地图级别等属性,如果父组件没有传入,则使用默认值。
第六步:添加 CafeMap 组件到 Cafes 页面
接下来,我们打开 resrouces/assets/js/pages/Cafes.vue
文件,引入上一步定义的 CafeMap.vue
组件并将其添加到当前页面:
import CafeMap from '../components/cafes/CafeMap.vue';
export default {
components: {
CafeMap
}
}
最后,在 Cafes.vue
页面上编写显示组件的 HTML 代码:
<template>
<div id="cafes">
<div class="grid-x">
<div class="large-9 medium-9 small-12 cell">
<cafe-map></cafe-map>
</div>
<div class="large-3 medium-3 small-12 cell">
</div>
</div>
</div>
</template>
在项目根目录下运行 npm run dev
重新构建项目,访问 http://roast.test
,然后点击 Cafes
链接,即可看到这个初始化的地图:
第七步:将咖啡店标记在地图上
最后的最后,也是最关键的一步,我们将在之前创建的 CafeMap.vue
组件中实现咖啡店在高德地图上的位置标记(对应高德地图上的点标记文档)。
打开 resources/assets/js/components/cafes/CafeMap.vue
组件,在模型数据中初始化点标记数组:
data() {
return {
markers: []
}
},
然后通过计算属性方式从 Vuex 中返回全局咖啡店列表数据:
computed: {
cafes(){
return this.$store.getters.getCafes;
}
},
最后在 methods
中通过 buildMarkers()
方法创建点标记:
methods: {
// 为所有咖啡店创建点标记
buildMarkers() {
// 清空点标记数组
this.markers = [];
// 遍历所有咖啡店并为每个咖啡店创建点标记
for (var i = 0; i < this.cafes.length; i++) {
// 通过高德地图 API 为每个咖啡店创建点标记并设置经纬度
var marker = new AMap.Marker({
position: AMap.LngLat(parseFloat(this.cafes[i].latitude), parseFloat(this.cafes[i].longitude)),
title: this.cafes[i].name
});
// 将每个点标记放到点标记数组中
this.markers.push(marker);
}
// 将所有点标记显示到地图上
this.map.add(this.markers);
}
}
此外,我们还要定义一个 clearMarkers()
方法用来在重绘地图时清除地图上的所有点标记:
// 从地图上清理点标记
clearMarkers() {
// 遍历所有点标记并将其设置为 null 从而从地图上将其清除
for (var i = 0; i < this.markers.length; i++) {
this.markers[i].setMap(null);
}
}
我们还是在 mounted()
中调用这两个方法,以便在初始化地图后可以立即为咖啡店添加点标记:
// 清除并重构点标记
this.clearMarkers();
this.buildMarkers();
最后还需要监听 cafes
数据的变化,一旦有更新,立即清除地图上的所有点标记并重新绘制:
watch: {
// 一旦 cafes 有更新立即重构地图点标记
cafes () {
this.clearMarkers();
this.buildMarkers();
}
}
至此,我们已完成了所有代码的编写,运行 npm run dev
重新构建前端资源,刷新 http://roast.test
,点击「Cafes」链接,即可看到我们在上一篇教程中新增的咖啡店标记了:
注:完整应用源码位于 nonfu/roastapp。
11 Comments
刷新http://roast.test/#/cafes这个页面就会出现错误,但是你先刷新http://roast.test/#/home 然后在点cafes跳转http://roast.test/#/cafes这个页面就不会出现错误了