|
大家好,这是一篇给自己的项目安利的软文[手动doge]
也许在你的 Web 项目里,会有一些需要加入地图的功能,举几个例子:
- 展示地址
- 展示订单的轨迹、状态
- 展示所有门店的分布
- 通过拖拽来选择一个点
要在Web页面中加入地图,我推荐你使用高德地图 JSAPI,而如果刚好你的项目是使用 VueJS 开发的,那么恭喜你,你正是这篇安利的最大受益者!
使用高德地图 JSAPI
与大多数面向 DOM 的库类似,高德地图 JSAPI 提供的 API 是命令式的。插入一个地图的过程大概是:
- 在 HTML 页面中引入高德地图 JSAPI 的 JS 文件
- 获取到 DOM 元素
- 将其作为容器,连同其它参数,传递给 new AMap.Map,创建一个地图实例
- 往地图里加入更多的元素
也就是
<!-- 引入高德地图JSAPI的JS文件 -->
<script type=&#34;text/javascript&#34; src=&#34;https://webapi.amap.com/maps?v=1.4.15&key=您申请的key值&#34;></script> 然后
// 获取到作为地图容器的DOM元素
const container = document.querySelector(&#39;#map-container&#39;)
// 创建地图实例
const map = new AMap.Map(container, {
center: [117.000923,36.675807],
zoom: 11
})
// 往地图里加入更多元素(如点标记)
const marker = new AMap.Marker({
map: map,
center: [117.000923,36.675807]
})
到了 Vue 项目里我们可能会遇到一些门槛:
- 在 HTML 里引入 JS 外链文件的做法和 Vue 工具链中常见的引入/构建方式(如 webpack)不太搭调
- 需要在 Vue 组件的 mounted() 里通过 $refs 拿到容器 DOM 元素,再去创建地图,再在 Vue 组件 beforeDestroyed() 里销毁刚才创建的地图
- 当你更新了数据时,需要手工调用地图、地图元素的各种 set 方法来同步修改它们的属性
可以见到上述开发体验是比较割裂的。
使用 AMap-Vue 来改善开发体验
AMap-Vue(npm: @amap/amap-vue)是一个基于 Vue 的高德地图 JSAPI 封装
使用它你可以帮助你:
- 组件化的地图开发,像普通视图组件一样使用地图
- 属性绑定、事件绑定、双向绑定、slot 等“Vue 风格”的声明式 API 特性
- 地图与 DOM UI 的无缝整合,一套数据,多处绑定
下面我会用尽可能简单的例子来帮助大家感受一下
组件化
对应上面那个例子,用 AMap-Vue 如何实现呢?
yarn add @amap/amap-vue # 或 npm install --save @amap/amap-vue
// 在Vue项目的入口文件中(如main.js)引入组件库
import AmapVue from &#39;@amap/amap-vue&#39;
AmapVue.config.key = &#39;您的JSAPI KEY&#39;
Vue.use(AmapVue)
<!-- 在你的template代码中使用地图系列的组件 -->
<div class=&#34;map-container&#34;>
<amap :zoom=&#34;11&#34; :center=&#34;[117.000923, 36.675807]&#34;>
<amap-marker :position=&#34;[117.000923, 36.675807]&#34; />
</amap>
</div>可以看出使用 AMap-Vue 和普通的 UI 组件库没有多少区别。
Vue 风格的声明式 API
声明式的 API 是 Vue 的一大特色,并且也是提升开发效率的利器,通过 AMap-Vue 你可以获得:
- 属性绑定
- 事件绑定
- 双向绑定(部分属性)
- v-for
- v-if
- slot(部分组件)
举几个简单的例子吧!
<!-- 使用v-if控制marker的显示与否 -->
<!-- 并对它的position属性进行双向绑定 -->
<amap-marker
v-if=&#34;showMarker&#34;
:position.sync=&#34;shop.position&#34;
:label=&#34;{
content: shop.name,
direction: &#39;bottom&#39;,
}&#34;
draggable
/>
<!-- 将门店列表数据绑定到多个多边形元素上 -->
<!-- 对它们的样式进行控制,高亮选中的门店 -->
<!-- 并且绑定它们的click事件,选中点击的门店 -->
<amap-polygon
v-for=&#34;shop in shops&#34;
:key=&#34;shop.id&#34;
:path=&#34;shop.polygon&#34;
:fill-opacity=&#34;shop === focusShop ? 0.8 : 0.4&#34;
:fill-color=&#34;rgb(255, 109, 154)&#34;
stroke-color=&#34;#000&#34;
clickable
@click=&#34;focusShop = shop&#34;
/>
<!-- 对信息窗体的visible、position属性进行绑定 -->
<!-- 并通过slot自定义它的内容 -->
<amap-info-window
:visible=&#34;showInfoWindow&#34;
:position=&#34;shop.position&#34;
auto-move
is-custom
>
<a-card>
<a-icon
type=&#34;close&#34;
@click=&#34;hideInfoWindow&#34;
/>
<h3>{{ shop.name }}</h3>
<p>
<label>地址:</label>
<span>{{ shop.address }}</span>
</p>
<my-gallery :data=&#34;shop.photos&#34; />
</a-card>
</amap-info-window>无缝整合地图与 UI
你可以将你的 UI 组件嵌套在 <amap> 地图组件之内,从而可以很方便的开发沉浸式的地图 UI 应用。
地图与 UI 在同一棵组件树上,意味着它们能统一地被 Vue 管理各种生命周期(例如:地图的 v-if 销毁时,它内部嵌套 UI 组件也会跟着一起销毁),减少你开发过程中维护两套生命周期的心智负担。
这样嵌套的关系也使得你的组件可以轻松地访问到 AMap.Map 实例对象,你的 UI 与地图之间能够实现更复杂的联合逻辑,亦或者引入其他基于高德地图生态的内容,比如数据可视化 JSAPI Loca。
例子:扩展自定义组件 | AMap-Vue
就是现在!为你的 Vue 项目加上高德地图吧!
相关资源
- npm: @amap/amap-vue
- 官网/文档: https://liuji-jim.github.io/amap-vue/
- 国内镜像:https://jimnox.gitee.io/amap-vue/
- 众所周知,国内访问GitHub Pages速度较慢
- 我正在争取将其迁移到高德开放平台官网上,届时就不会再有这个烦恼了
- 反馈: GitHub - LiuJi-Jim/amap-vue
- 高德地图 JSAPI 官网:概述、教程、参考手册
- 游乐场: 你可以通过这个 codesandbox 模板来快速体验基于 AMap-Vue 的地图应用开发

预先回答几个你可能会问的问题
是否官方?
目前不是 100% 官方性质,意味着
- 你无法通过高德开放平台官网来提问或者反馈来获得技术支持
- 但如果你确实提了工单,那么内部应该还是能转到我这里来回复的
- 我正在努力将它完全官方化,当然这个过程中自然也离不开你们的多多使用与反馈
是否开源?
目前没有开源
- 首先这需要建立在把它“扶正”成为高德开放平台的官方项目的基础之上
- 其次还需要经过一系列略微有一丢丢复杂的内部流程
是否封装了高德地图 UI 组件库(AMapUI)?
没有
- AMapUI 的 UI 样式并不一定适合所有项目
- 尤其是当你的项目已经使用了 Vue 生态中的各种 UI 组件库时
- 基于 Vue 的强大生态,结合组件化/声明式的开发方式,你可以快速实现自己的地图 UI
- 或者通过扩展自定义组件的方式来开发地图逻辑更复杂的组件
与 vue-amap 的关系/对比?
vue-amap 是由 ElemeFE 开发的一个类似的库,二者有不少相似之处
- 相比之下,@amap/amap-vue 的优势,个人认为主要有
- 也许更完整的高德地图 JSAPI 功能覆盖面
- 也许更强大易用的属性绑定/事件绑定/双向绑定
- 缺点呢,最大的缺点自然是尚未开源,但相信这只是暂时的
|
|