├── README.md
├── babel.config.js
├── package-lock.json
├── package.json
├── public
├── favicon.ico
└── index.html
└── src
├── App.vue
├── assets
└── logo.png
├── components
└── mapDrag.vue
├── config
└── config.js
├── main.js
└── utils
└── remoteLoad.js
/README.md:
--------------------------------------------------------------------------------
1 | # 在Vue中完美的使用高德地图
2 |
3 | > 最近项目中有使用到高德地图,搜了下发现饿了么的 vue-amap 比较知名。不过实际安装使用中发现还是有很多问题的,并不友好。不但要学习 amap 的文档,也还要学习原生高德API文档,还不如直接使用原生来的方便。
4 |
5 | 而这篇教程的目的就是,**怎么在vue中使用高德地图API**
6 |
7 | 文档:[Demo和使用文档](http://vue-gaode.rxshc.com)
8 |
9 | ## 运行项目
10 | ``` s
11 | # 安装依赖
12 | npm install
13 | # 运行项目
14 | npm run serve
15 | ```
16 |
17 | ## 实现思路
18 |
19 | * 创建一个 mapDrag 的公共组件
20 | * 在组件的 created 生命周期,载入高德地图API
21 | * API载入完成即开始执行地图初始化
22 | * 地图API暴露全局变量 window.AMap 可以直接使用
23 | * 监听地图拖放事件,获得数据后通知自定义事件,对组件外部提供事件接口
24 |
25 | ## created 生命周期载入高德地图API
26 |
27 | 载入的方式类似于 jquery 的脚本加载,我这里也是使用了别人封装好的一个加载方法,各位直接使用或者自己改
28 |
29 | ``` javascript
30 | async created () {
31 | // 已载入高德地图API,则直接初始化地图
32 | if (window.AMap && window.AMapUI) {
33 | this.initMap()
34 | // 未载入高德地图API,则先载入API再初始化
35 | } else {
36 | await remoteLoad(`http://webapi.amap.com/maps?v=1.3&key=${MapKey}`)
37 | await remoteLoad('http://webapi.amap.com/ui/1.0/main.js')
38 | this.initMap()
39 | }
40 | }
41 | ```
42 | ## 初始化地图
43 | 在 methods 中创建一个 initMap 的方法供载入地图API之后调用。这里就可以使用任意高德API
44 | ``` javascript
45 | initMap () {
46 | // 加载PositionPicker,loadUI的路径参数为模块名中 'ui/' 之后的部分
47 | let AMapUI = this.AMapUI = window.AMapUI
48 | let AMap = this.AMap = window.AMap
49 | AMapUI.loadUI(['misc/PositionPicker'], PositionPicker => {
50 | let mapConfig = {
51 | zoom: 16,
52 | cityName: MapCityName
53 | }
54 | if (this.lat && this.lng) {
55 | mapConfig.center = [this.lng, this.lat]
56 | }
57 | let map = new AMap.Map('js-container', mapConfig)
58 | // 加载地图搜索插件
59 | AMap.service('AMap.PlaceSearch', () => {
60 | this.placeSearch = new AMap.PlaceSearch({
61 | pageSize: 5,
62 | pageIndex: 1,
63 | citylimit: true,
64 | city: MapCityName,
65 | map: map,
66 | panel: 'js-result'
67 | })
68 | })
69 | // 启用工具条
70 | AMap.plugin(['AMap.ToolBar'], function () {
71 | map.addControl(new AMap.ToolBar({
72 | position: 'RB'
73 | }))
74 | })
75 | // 创建地图拖拽
76 | let positionPicker = new PositionPicker({
77 | mode: 'dragMap', // 设定为拖拽地图模式,可选'dragMap'、'dragMarker',默认为'dragMap'
78 | map: map // 依赖地图对象
79 | })
80 | // 拖拽完成发送自定义 drag 事件
81 | positionPicker.on('success', positionResult => {
82 | // 过滤掉初始化地图后的第一次默认拖放
83 | if (!this.dragStatus) {
84 | this.dragStatus = true
85 | } else {
86 | this.$emit('drag', positionResult)
87 | }
88 | })
89 | // 启动拖放
90 | positionPicker.start()
91 | })
92 | }
93 | ```
94 |
95 | ## 调用
96 | ``` html
97 |
98 | ```
99 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/app'
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue-gaode",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint"
9 | },
10 | "dependencies": {
11 | "highlight.js": "^9.12.0",
12 | "vue": "^2.5.17"
13 | },
14 | "devDependencies": {
15 | "@vue/cli-plugin-babel": "^3.0.1",
16 | "@vue/cli-plugin-eslint": "^3.0.1",
17 | "@vue/cli-service": "^3.0.1",
18 | "vue-template-compiler": "^2.5.17"
19 | },
20 | "eslintConfig": {
21 | "root": true,
22 | "env": {
23 | "node": true
24 | },
25 | "extends": [
26 | "plugin:vue/essential",
27 | "eslint:recommended"
28 | ],
29 | "rules": {},
30 | "parserOptions": {
31 | "parser": "babel-eslint"
32 | }
33 | },
34 | "postcss": {
35 | "plugins": {
36 | "autoprefixer": {}
37 | }
38 | },
39 | "browserslist": [
40 | "> 1%",
41 | "last 2 versions",
42 | "not ie <= 8"
43 | ]
44 | }
45 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zuley/vue-gaode/993fe3f058f85d7fd35fe1d00fe3abe30c9a4c0d/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | 在Vue中完美的使用高德地图
9 |
10 |
11 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
11 |
拖拽选址 - DEMO
12 |
13 |
14 | - 经度:{{ dragData.lng }}
15 | - 纬度:{{ dragData.lat }}
16 | - 地址:{{ dragData.address }}
17 | - 最近的路口:{{ dragData.nearestJunction }}
18 | - 最近的路:{{ dragData.nearestRoad }}
19 | - 最近的POI:{{ dragData.nearestPOI }}
20 |
21 |
22 |
23 |
教程说明
24 |
最近项目中有使用到高德地图,搜了下发现饿了么的 vue-amap 比较知名。不过实际安装使用中发现还是有很多问题的,并不友好。不但要学习 amap 的文档,也还要学习原生高德API文档,还不如直接使用原生来的方便。
25 |
而这篇教程的目的就是,怎么在vue中使用高德地图API
26 |
源码:View on GitHub(为方便大家测试使用的是我本人的key,仅用于测试不要用于线上环境)
27 |
28 |
29 |
实现思路
30 |
以一个拖放地图的例子来解释,DEMO在上方
31 |
32 | - 创建一个 mapDrag 的公共组件
33 | - 在组件的 created 生命周期,载入高德地图API
34 | - API载入完成即开始执行地图初始化
35 | - 地图API暴露全局变量 window.AMap 可以直接使用
36 | - 监听地图拖放事件,获得数据后通知自定义事件,对组件外部提供事件接口
37 |
38 |
39 |
40 |
created 生命周期载入高德地图API
41 |
载入的方式类似于 jquery 的脚本加载,我这里也是使用了别人封装好的一个加载方法,各位直接使用或者自己改
42 |
43 | async created () {
44 | // 已载入高德地图API,则直接初始化地图
45 | if (window.AMap && window.AMapUI) {
46 | this.initMap()
47 | // 未载入高德地图API,则先载入API再初始化
48 | } else {
49 | await remoteLoad(`http://webapi.amap.com/maps?v=1.3&key=${MapKey}`)
50 | await remoteLoad('http://webapi.amap.com/ui/1.0/main.js')
51 | this.initMap()
52 | }
53 | }
54 |
55 |
56 |
初始化地图
57 |
在 methods 中创建一个 initMap 的方法供载入地图API之后调用。这里就可以使用任意高德API
58 |
59 | initMap () {
60 | // 加载PositionPicker,loadUI的路径参数为模块名中 'ui/' 之后的部分
61 | let AMapUI = this.AMapUI = window.AMapUI
62 | let AMap = this.AMap = window.AMap
63 | AMapUI.loadUI(['misc/PositionPicker'], PositionPicker => {
64 | let mapConfig = {
65 | zoom: 16,
66 | cityName: MapCityName
67 | }
68 | if (this.lat && this.lng) {
69 | mapConfig.center = [this.lng, this.lat]
70 | }
71 | let map = new AMap.Map('js-container', mapConfig)
72 | // 加载地图搜索插件
73 | AMap.service('AMap.PlaceSearch', () => {
74 | this.placeSearch = new AMap.PlaceSearch({
75 | pageSize: 5,
76 | pageIndex: 1,
77 | citylimit: true,
78 | city: MapCityName,
79 | map: map,
80 | panel: 'js-result'
81 | })
82 | })
83 | // 启用工具条
84 | AMap.plugin(['AMap.ToolBar'], function () {
85 | map.addControl(new AMap.ToolBar({
86 | position: 'RB'
87 | }))
88 | })
89 | // 创建地图拖拽
90 | let positionPicker = new PositionPicker({
91 | mode: 'dragMap', // 设定为拖拽地图模式,可选'dragMap'、'dragMarker',默认为'dragMap'
92 | map: map // 依赖地图对象
93 | })
94 | // 拖拽完成发送自定义 drag 事件
95 | positionPicker.on('success', positionResult => {
96 | // 过滤掉初始化地图后的第一次默认拖放
97 | if (!this.dragStatus) {
98 | this.dragStatus = true
99 | } else {
100 | this.$emit('drag', positionResult)
101 | }
102 | })
103 | // 启动拖放
104 | positionPicker.start()
105 | })
106 | }
107 |
108 |
109 |
调用
110 |
<mapDrag @drag="dragMap" lat="22.574405" lng="114.095388"></mapDrag>
111 |
112 |
113 |
114 |
115 |
116 |
117 |
150 |
151 |
175 |
--------------------------------------------------------------------------------
/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zuley/vue-gaode/993fe3f058f85d7fd35fe1d00fe3abe30c9a4c0d/src/assets/logo.png
--------------------------------------------------------------------------------
/src/components/mapDrag.vue:
--------------------------------------------------------------------------------
1 |
14 |
15 |
16 |
21 |
正在加载数据 ...
22 |
23 |
24 |
25 |
116 |
117 |
125 |
--------------------------------------------------------------------------------
/src/config/config.js:
--------------------------------------------------------------------------------
1 | // 高德地图 key
2 | export const MapKey = 'cfd8da5cf010c5f7441834ff5e764f5b'
3 | // 地图限定城市
4 | export const MapCityName = '深圳'
5 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 |
4 | import hljs from 'highlight.js'
5 | import 'highlight.js/styles/railscasts.css'
6 |
7 | Vue.directive('hljs', el => {
8 | let blocks = el.querySelectorAll('pre')
9 | Array.prototype.forEach.call(blocks, hljs.highlightBlock)
10 | })
11 |
12 | Vue.config.productionTip = false
13 |
14 | new Vue({
15 | render: h => h(App)
16 | }).$mount('#app')
17 |
--------------------------------------------------------------------------------
/src/utils/remoteLoad.js:
--------------------------------------------------------------------------------
1 | export default function remoteLoad (url, hasCallback) {
2 | return createScript(url)
3 | /**
4 | * 创建script
5 | * @param url
6 | * @returns {Promise}
7 | */
8 | function createScript (url) {
9 | let scriptElement = document.createElement('script')
10 | document.body.appendChild(scriptElement)
11 | let promise = new Promise((resolve, reject) => {
12 | scriptElement.addEventListener('load', e => {
13 | removeScript(scriptElement)
14 | if (!hasCallback) {
15 | resolve(e)
16 | }
17 | }, false)
18 |
19 | scriptElement.addEventListener('error', e => {
20 | removeScript(scriptElement)
21 | reject(e)
22 | }, false)
23 |
24 | if (hasCallback) {
25 | window.____callback____ = function () {
26 | resolve()
27 | window.____callback____ = null
28 | }
29 | }
30 | })
31 |
32 | if (hasCallback) {
33 | url += '&callback=____callback____'
34 | }
35 |
36 | scriptElement.src = url
37 |
38 | return promise
39 | }
40 |
41 | /**
42 | * 移除script标签
43 | * @param scriptElement script dom
44 | */
45 | function removeScript (scriptElement) {
46 | document.body.removeChild(scriptElement)
47 | }
48 | }
49 |
--------------------------------------------------------------------------------