最近在写外卖的项目,必然逃不过要跟地图组件打交道。 在
Vue
项目中,一般有外部组件需求的时候,首先会到官方三宝中扒一扒
- Vue官方仓库 https://curated.vuejs.org/
- Vue优选组件 https://github.com/vuejs
- Vue资源汇总 https://github.com/vuejs/awesome-vue
vue-baidu-map 百度地图
加分:文档较详细好用,使用方便 减分:功能相对较少,不过够用了
vue-amap 高德地图(非官方)
加分:做了基本用法的封装,使代码风格更偏向于Vue,可与原生AMap混用
减分:开发自万能的饿厂,之前用过 element-ui 的同学都晓得其中的苦,文档不够详细,很多用法要自己一遍一遍尝试,出了问题只能到 gayhub
查 Issues
[逃.gif]…
amap 高德地图(原生)
加分:只有想不到,没有做不到,基本满足任何PM的变态需求 减分:…
上原生
可能不是最佳实践,但是简单暴力
1. 首先在项目入口文件 index.html
中引入 AMap
,没错只要一行
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black"/>
<title>AMap-demo</title>
<script type="text/javascript" src="http://webapi.amap.com/maps?v=1.4.2&key=您申请的key值"></script> <!-- 高德地图 -->
</head>
<body>
<div id="app"></div>
</body>
</html>
2. 在 template
中选定地图的div容器,在 script
中调用地图
Demo: http://lbs.amap.com/api/javascript-api/example/map/map-show
<template>
<div class="demo-wrap">
<div id="container" style="width:500px; height:300px"></div>
</div>
</template>
export default {
data(){
return{
}
},
mounted(){
let map = new AMap.Map('container',{
zoom: 12,
center: [116.39,39.9]
})
}
}
到这里,不出意外的话地图就出现了。
如果报错了,可能是引入失败,另外没有引入时没有 key
值是不会报错的。
如果没有报错而地图不显示,可能是:
1.没有设置地图容器宽高
2.地图被定位元素遮挡,尝试设置定位属性并提升 z-index
值
3.没有初始化地图,或者初始化地图的方法没有被执行
4.地图显示,但是没有内容只有蓝蓝的一片,恭喜啦可能是你定位到了海里 [雾.gif]…,把 zoom
设置的小一些看下当前位置
3. 组件用例 点标记
正常我们在项目中,可能不会写一堆全丢进 mounted/created
里,把初始化和组件调用写在方法里,在需要的时候调用,方便解耦复用减少重复代码,比如这样:
Demo: http://lbs.amap.com/api/javascript-api/example/marker/marker-content
export default {
data(){
return{
}
},
mounted(){
this.zoom = 14
this.center = [121.59996, 31.197646]
this.map_ = new AMap.Map("amap-wrap", { //初始化地图
zoom: this.zoom,
center: this.center
})
this.setMarker('marker1',[121.59997, 31.197647]) //点标记1
this.setMarker('marker2',[121.59967, 31.197667]) //点标记2
},
methods:{
setMarker(markers,position){ //添加点标记
this.markers = new AMap.Marker({
position: position,
map: this.map_ //把点标记绑在前面初始化的 map_ 上,否则不显示
})
},
}
}
4. 组件用例 点标记模拟位置移动
这里有个比较难受的问题,就是在Vue中,我们习惯在 data(){return{}}
中初始变量,然后在其他地方去赋值操作。这个对于 amap
是不生效的,需要直接用 this
注册在 Vue
实例上,所以当我们需要操作同一个变量的时候,比如改变中心点坐标,或者点标记坐标的时候,就需要清除上一个值,并赋新值。
比如模拟一个点坐标的移动:
Demo: http://lbs.amap.com/api/javascript-api/example/marker/replaying-historical-running-data
export default {
data(){
return{
}
},
mounted(){
this.zoom = 14
this.center = [121.59996, 31.197646]
this.map_ = new AMap.Map("amap-wrap", { //初始化地图
zoom: this.zoom,
center: this.center
})
this.setMarker()
},
methods:{
setMarker(){ //添加点标记
let x = this.center[0]
let y = this.center[1]
setInterval(()=>{ //模拟骑手位置移动
x+=0.0001
y+=0.0001
console.log(x,y)
let marker = new AMap.Marker({ //设置下一个点坐标
icon : 'https://www.xxx.com/xxx/images/sender_icon.png', //自定义点坐标图片
position : [x, y],
map : this.map_
})
setInterval(()=>{
marker.setMap() //置空上一个点坐标
},2000)
},2000)
},
}
}
5. 组件用例 圆半径范围
Demo: http://lbs.amap.com/api/javascript-api/example/overlayers/polyline-circle-polygon
export default {
data(){
return{
}
},
mounted(){
this.zoom = 14
this.center = [121.59996, 31.197646]
this.map_ = new AMap.Map("amap-wrap", { //初始化地图
zoom: this.zoom,
center: this.center
})
this.setCircle()
},
methods:{
setCircle(){ //添加圆形范围
this.circle = new AMap.Circle({
center: this.center, //圆心位置
radius: 3000, //半径
strokeColor: "#2395ff", //线颜色
strokeOpacity: .2, //线透明度
strokeWeight: 1, //线粗细度
fillColor: "#2395ff", //填充颜色
fillOpacity: .2, //填充透明度
map: this.map_
})
},
}
}
6. 组件用例 定位到当前位置按钮
Demo: http://lbs.amap.com/api/javascript-api/example/location/browser-location
export default {
data(){
return{
}
},
mounted(){
this.zoom = 14
this.center = [121.59996, 31.197646]
this.map_ = new AMap.Map("amap-wrap", { //初始化地图
zoom: this.zoom,
center: this.center
})
this.setGeolocation()
},
methods:{
setGeolocation(){ //添加定位btn
this.map_.plugin('AMap.Geolocation', ()=>{
this.geolocation = new AMap.Geolocation({
enableHighAccuracy: true, //是否使用高精度定位,默认:true
timeout: 5000, //超过10秒后停止定位,默认:无穷大
buttonOffset: new AMap.Pixel(10, 10), //定位按钮与设置的停靠位置的偏移量,默认:Pixel(10, 20)
zoomToAccuracy: true, //定位成功后调整地图视野范围使定位位置及精度范围视野内可见,默认:false
buttonPosition:'RB'
})
this.map_.addControl(this.geolocation)
this.geolocation.getCurrentPosition()
AMap.event.addListener(this.geolocation, 'complete', (res)=>{console.log(res)}) //定位成功返回值
AMap.event.addListener(this.geolocation, 'error', (res)=>{console.log(res)}) //定位失败返回值
})
},
}
}
7. 组件用例 点击地图选点
export default {
data(){
return{
}
},
mounted(){
this.zoom = 14
this.center = [121.59996, 31.197646]
this.map_ = new AMap.Map("amap-wrap", { //初始化地图
zoom: this.zoom,
center: this.center
})
this.Geocoder()
},
methods:{
Geocoder(){ //添加定位btn
this.map_.plugin('AMap.Geocoder',()=>{
this.geocoder = new AMap.Geocoder({
city: "010"//城市,默认:“全国”
});
this.marker = new AMap.Marker({
map:this.map_,
bubble:true
})
this.map_.on('click',(e)=>{
this.marker.setPosition(e.lnglat)
this.geocoder.getAddress(e.lnglat,(status,result)=>{
if(status=='complete'){
let addr_detail = result.regeocode.addressComponent
this.addr_name = addr_detail.province + addr_detail.city + addr_detail.district + addr_detail.township + addr_detail.street
console.log(result.regeocode.addressComponent) //选点地址
console.log([e.lnglat.lng,e.lnglat.lat]) //选点经纬度
}else{
console.log('无法获取地址')
}
})
})
})
},
}
}
8. 组件用例 设置多边形范围选区(移动端滑动手势)
Demo: http://lbs.amap.com/others/demo_list/demos/map_drawcust.html Demo code: view-source:http://lbs.amap.com/others/demo_list/demos/map_drawcust.html
export default {
data(){
return{
}
},
mounted(){
this.zoom = 14
this.center = [121.59996, 31.197646]
this.map_ = new AMap.Map("amap-wrap", { //初始化地图
zoom: this.zoom,
center: this.center
})
//通过touchstart和touchmove,捕获手势坐标,连接为多边形的边线
let _this = this
let polyline
let arr = []
AMap.event.addListener(map_, 'touchstart', function (e) {
polyline = new AMap.Polyline({
map: map_,
path: []
})
})
AMap.event.addListener(map_, 'touchmove', function (e) {
if (arr.length <= 1) arr.push(e.lnglat)
let len = arr.length, obj = arr[len - 1]
if (len >= 1 && (obj.lng !== e.lnglat.lng || obj.lat !== e.lnglat.lat)) arr.push(e.lnglat)
polyline.setPath(arr)
})
AMap.event.addListener(map_, 'touchend', function (e) {
let polygon = new AMap.Polygon({
map: map_,
path: arr
})
_this.send_range = arr
polyline.setMap(null)
console.log(_this.send_range) //这里可以看到选区的坐标集合的数组
})
},
methods:{
}
}
9. 组件用例 展示多边形范围选区
Demo: http://lbs.amap.com/api/javascript-api/example/overlayers/polyline-circle-polygon
export default {
data(){
return{
}
},
mounted(){
this.zoom = 14
this.center = [121.59996, 31.197646]
this.map_ = new AMap.Map("amap-wrap", { //初始化地图
zoom: this.zoom,
center: this.center
})
this.setPolygon()
},
methods:{
setPolygon(){ //设置多边形边界路径
let send_range = [
[116.403322, 39.920255],
[116.410703, 39.897555],
[116.402292, 39.892353],
[116.389846, 39.891365]
]
this.polygon = new AMap.Polygon({
path: send_range, //配送范围
strokeColor: "#2395ff", //线颜色
strokeOpacity: .2, //线透明度
strokeWeight: 3, //线宽
fillColor: "#2395ff", //填充色
fillOpacity: .35, //填充透明度
map:this.map_
})
}
}
OK 暂时用到的就这么多,打完收工 [逃.gif]…