小知识,大挑战!本文正在参与“程序员必备小知识”创作活动
TIP 👉 道高一尺,魔高一丈。吴承恩《西游记》
前言
在我们日常项目开发中,我们可能会会涉及到地图功能,所以封装了这款地图组件。地图定位组件
属性
1. value
- 位置信息
- 值为对象
- 值示例:
{
address: '北京市朝阳区奥运村街道奥林匹克森林公园奥林匹克森林公园南园',
lng: 116.389006,
lat: 40.015535
}
2. editable
- 是否可编辑(即修改位置)
- 值为布尔类型
- 默认值为 false
样式要求
- 组件外面需要包裹可以相对定位的元素,增加样式:
position: relative
示例
<template>
<div class="amap-demo">
<ul class="form-list">
<li class="form-item" @click="popupBox1">
<div class="item-content">
<label>位置查看:</label>
<span>{{value1 && value1.address}}</span>
</div>
<div class="arrow">
<Icon name="right-arrow"></Icon>
</div>
</li>
<li class="form-item" @click="popupBox2">
<div class="item-content">
<label>位置定位:</label>
<span>{{value2 && value2.address}}</span>
</div>
<div class="arrow">
<Icon name="right-arrow"></Icon>
</div>
</li>
</ul>
</div>
</template>
<script>
import popupFullBox from '@/components/m/fullBox'
import AMap from '@/components/base/amap/AMap.vue'
export default {
name: 'AMapDemoM',
data () {
return {
value1: {
address: '北京市朝阳区奥运村街道奥林匹克森林公园奥林匹克森林公园南园',
lng: 116.389006,
lat: 40.015535
},
value2: null
}
},
methods: {
popupBox1 () {
popupFullBox({
title: '位置查看',
scroll: false,
content: AMap,
contentProps: {
value: this.value1
}
})
},
popupBox2 () {
popupFullBox({
title: '地图定位',
scroll: false,
content: AMap,
contentProps: {
value: this.value2,
editable: true
},
contentEvents: {
changePosition: (v) => {
this.value2 = v
}
}
})
}
}
}
</script>
实现Map.vue
<!-- 地图定位组件 -->
<template>
<div class="map-container">
<div class="loading" v-if="loading">
<BaseSpinner spinner="circles"></BaseSpinner>
</div>
<div :id="'amap_' + id" class="map-content">
</div>
</div>
</template>
<script>
// https://lbs.amap.com/api/webservice/summary
import BaseSpinner from '@/components/base/spinner'
import { generateUUID, loadScript } from '@/assets/js/utils.js'
import amapConf from './amap-conf.js'
export default {
name: 'AMap',
components: {
BaseSpinner
},
props: {
// 位置信息
value: {
type: Object
},
// 是否可编辑(即更改位置数据)
editable: {
type: Boolean,
default: false
}
},
data () {
return {
curValue: this.value && this.value.lat && this.value.lng ? this.value : null,
id: generateUUID(),
loading: false
}
},
watch: {
value (val) {
this.curValue = val
}
},
mounted () {
this.showMap()
},
methods: {
showMap () {
this.loading = true
this.loadScripts().then((result) => {
// console.log('############# loadScripts', result)
result && this.initMap()
})
},
initMap () {
let map = new window.AMap.Map('amap_' + this.id, {
resizeEnable: true,
zoom: 14
})
map.on('complete', () => {
this.loading = false
})
if (this.editable) {
window.AMapUI.loadUI(['misc/PositionPicker', 'misc/PoiPicker'], (PositionPicker, PoiPicker) => {
let picker = new PositionPicker({
map,
mode: 'dragMap'
})
picker.on('success', (positionResult) => {
let value = {
address: positionResult.address,
lat: positionResult.position.lat,
lng: positionResult.position.lng
}
this.curValue = value
this.$emit('changePosition', value)
this.$emit('input', value)
// console.log('定位成功: ', positionResult)
})
if (this.curValue) {
// console.log('picker.start([this.curValue.lng, this.curValue.lat])', this.curValue.lng, this.curValue.lat)
picker.start([this.curValue.lng, this.curValue.lat])
} else {
picker.start()
}
})
} else {
let value = this.curValue // { address: '北京市东城区东华门街道天安门广场', lat: 39.906504, lng: 116.397732 }
if (value) {
let position = [this.curValue.lng, this.curValue.lat]
let marker = new window.AMap.Marker({
position: position,
title: value.address
})
marker.setMap(map)
marker.on('click', () => {
this.$toast({ position: 'top', message: value.address })
})
map.setCenter(position)
}
}
},
// 加载脚本
loadScripts () {
return loadScript('http://webapi.amap.com/maps?v=1.4.8&key=' + amapConf.key, 'amap_maps').then(() => {
return loadScript('http://webapi.amap.com/ui/1.0/main.js?v=1.0.11', 'amap_ui').then(() => {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (!window.AMap) {
console.error('地图加载失败!')
resolve(false)
} else {
resolve(true)
}
}, 100)
})
})
})
}
}
}
</script>
<style lang="scss" scoped>
.map-container {
.map-content {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.loading {
text-align: center;
height: 300px;
}
}
</style>
key
/**
* 高德地图开放接口配置
* @date 2021/2/2
*/
export default {
// Web服务API密钥
key: '1111111'
}
「欢迎在评论区讨论」