查看: 117|回复: 21

为你的Vue项目加上高德地图

[复制链接]

1

主题

2

帖子

4

积分

新手上路

Rank: 1

积分
4
发表于 2022-9-21 15:03:07 | 显示全部楼层 |阅读模式
大家好,这是一篇给自己的项目安利的软文[手动doge]
也许在你的 Web 项目里,会有一些需要加入地图的功能,举几个例子:

  • 展示地址
  • 展示订单的轨迹、状态
  • 展示所有门店的分布
  • 通过拖拽来选择一个点
要在Web页面中加入地图,我推荐你使用高德地图 JSAPI,而如果刚好你的项目是使用 VueJS 开发的,那么恭喜你,你正是这篇安利的最大受益者!
使用高德地图 JSAPI

与大多数面向 DOM 的库类似,高德地图 JSAPI 提供的 API 是命令式的。插入一个地图的过程大概是:

  • 在 HTML 页面中引入高德地图 JSAPI 的 JS 文件
  • 获取到 DOM 元素
  • 将其作为容器,连同其它参数,传递给 new AMap.Map,创建一个地图实例
  • 往地图里加入更多的元素
也就是
<!-- 引入高德地图JSAPI的JS文件 -->
<script type="text/javascript" src="https://webapi.amap.com/maps?v=1.4.15&key=您申请的key值"></script> 然后
// 获取到作为地图容器的DOM元素
const container = document.querySelector('#map-container')
// 创建地图实例
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 '@amap/amap-vue'

AmapVue.config.key = '您的JSAPI KEY'
Vue.use(AmapVue)

  • 使用组件
<!-- 在你的template代码中使用地图系列的组件 -->
<div class="map-container">
  <amap :zoom="11" :center="[117.000923, 36.675807]">
    <amap-marker :position="[117.000923, 36.675807]" />
  </amap>
</div>可以看出使用 AMap-Vue 和普通的 UI 组件库没有多少区别。
Vue 风格的声明式 API

声明式的 API 是 Vue 的一大特色,并且也是提升开发效率的利器,通过 AMap-Vue 你可以获得:

  • 属性绑定
  • 事件绑定
  • 双向绑定(部分属性)
  • v-for
  • v-if
  • slot(部分组件)
举几个简单的例子吧!
<!-- 使用v-if控制marker的显示与否 -->
<!-- 并对它的position属性进行双向绑定 -->
<amap-marker
  v-if="showMarker"
  :position.sync="shop.position"
  :label="{
    content: shop.name,
    direction: 'bottom',
  }"
  draggable
/>

<!-- 将门店列表数据绑定到多个多边形元素上 -->
<!-- 对它们的样式进行控制,高亮选中的门店 -->
<!-- 并且绑定它们的click事件,选中点击的门店 -->
<amap-polygon
  v-for="shop in shops"
  :key="shop.id"
  :path="shop.polygon"
  :fill-opacity="shop === focusShop ? 0.8 : 0.4"
  :fill-color="rgb(255, 109, 154)"
  stroke-color="#000"
  clickable
  @click="focusShop = shop"
/>

<!-- 对信息窗体的visible、position属性进行绑定 -->
<!-- 并通过slot自定义它的内容 -->
<amap-info-window
  :visible="showInfoWindow"
  :position="shop.position"
  auto-move
  is-custom
>
  <a-card>
    <a-icon
      type="close"
      @click="hideInfoWindow"
    />
    <h3>{{ shop.name }}</h3>
    <p>
      <label>地址:</label>
      <span>{{ shop.address }}</span>
    </p>
    <my-gallery :data="shop.photos" />
  </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 功能覆盖面
    • 也许更强大易用的属性绑定/事件绑定/双向绑定

  • 缺点呢,最大的缺点自然是尚未开源,但相信这只是暂时的
回复

使用道具 举报

1

主题

4

帖子

5

积分

新手上路

Rank: 1

积分
5
发表于 2022-9-21 15:03:31 | 显示全部楼层
恭喜恭喜,终于发布了
回复

使用道具 举报

1

主题

4

帖子

3

积分

新手上路

Rank: 1

积分
3
发表于 2022-9-21 15:03:40 | 显示全部楼层
感觉会用到,先收藏
回复

使用道具 举报

3

主题

9

帖子

10

积分

新手上路

Rank: 1

积分
10
发表于 2022-9-21 15:04:18 | 显示全部楼层
amap-vue半年都没有更新过了,使用起来也感觉很鸡劣,没有直接使用原生的高德js方便。
回复

使用道具 举报

2

主题

10

帖子

19

积分

新手上路

Rank: 1

积分
19
发表于 2022-9-21 15:04:33 | 显示全部楼层
厉害了,用高德很多的,以后大概率会用到
回复

使用道具 举报

1

主题

6

帖子

3

积分

新手上路

Rank: 1

积分
3
发表于 2022-9-21 15:05:19 | 显示全部楼层
高德地图,持续为你导航(到厕所)
回复

使用道具 举报

1

主题

4

帖子

5

积分

新手上路

Rank: 1

积分
5
发表于 2022-9-21 15:06:08 | 显示全部楼层
不能这样黑志玲[doge]
回复

使用道具 举报

1

主题

3

帖子

4

积分

新手上路

Rank: 1

积分
4
发表于 2022-9-21 15:07:08 | 显示全部楼层
111
回复

使用道具 举报

2

主题

4

帖子

8

积分

新手上路

Rank: 1

积分
8
发表于 2022-9-21 15:07:23 | 显示全部楼层
先点个赞
回复

使用道具 举报

2

主题

11

帖子

21

积分

新手上路

Rank: 1

积分
21
发表于 2022-9-21 15:08:05 | 显示全部楼层
不知道API是否和amap一样丰富
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表