├── 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 | 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 | 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 | --------------------------------------------------------------------------------