騰訊地圖選擇地址進階版(二)
使用騰訊地圖的地圖組件,獲取用戶經緯度和當前地址
之前也寫過一篇 vue中使用騰訊地圖選擇地址
不過不太完善。因爲畢竟要跳轉新的頁面選擇在回調回來,最近也發現了一些新的坑!今天來填坑了
騰訊地圖相關文檔
申請騰訊地圖的我就不多敘述,跟着提示申請即可
效果圖:
寫成組件
之前採用的是第二種方式,直接跳轉新頁面,後來還是問題很多,所以我改成了用 iframe
的形式,並且寫成組件
直接貼代碼吧(頂部用的是vant的組件):
<!-- components/Qqmap.vue -->
<template>
<div class="map">
<van-nav-bar left-arrow left-text="返回" title="選擇地址" @click-left="$emit('hideMap')" />
<iframe id="mapPage" width="100%" height="100%" frameborder=0 :src="getSrc">
</iframe>
</div>
</template>
<script>
export default {
name: 'QqMap',
data() {
return {}
},
computed: {
getSrc() {
var baseUrl = 'https://apis.map.qq.com/tools/locpicker?search=1&type=1&key=' + this.mapKey + '&referer=' + this.keyName
if (this.lat && this.lng) {
baseUrl += `&coord=${this.lat},${this.lng}`
}
return baseUrl
}
},
props: {
mapKey: {
type: String,
default: ''
},
keyName: {
type: String,
default: ''
},
lat: {
type: [String, Number]
},
lng: {
type: [String, Number]
}
},
mounted() {
var self = this
window.addEventListener('message', function(event) {
// 對於無法識別的地址,直接返回無法選擇
var loc = event.data
if (loc.poiname === '我的位置' || loc.poiaddress === '') {
self.$toast('無法識別該地址,請移動地圖重新選擇')
return false
}
if (loc && loc.module === 'locationPicker') { // 防止其他應用也會向該頁面post信息,需判斷module是否爲'locationPicker'
self.$emit('callback', loc)
}
}, false)
}
}
</script>
<style lang="scss" scoped>
.map {
width: 100%;
height: 100%;
}
</style>
使用組件
<!-- 在需要使用的頁面 -->
<!-- 注意,頁面上很多變量都是程序的代碼,自行排除哈。還有全國省市區的數組在下面有顯示 -->
<template>
<div>
<!-- ... -->
<!-- 彈出地圖選擇(這裏用的也是vant的彈出組件) -->
<van-popup v-model="showMap" position="right" :style="{ height: '100%',width:'100%' }">
<qq-map :map-key="mapKey" :key-name="keyName" @callback="callback" @hideMap="showMap = false"></qq-map>
<!-- :lat="settings.store_latitude"
:lng="settings.store_longitude" -->
</van-popup>
<!-- ... -->
</div>
</template>
<script>
import QqMap from '@/components/QqMap'
export default {
data() {
return {
showMap: false,
}
},
components: {
QqMap
},
methods: {
// 地圖選擇回調
callback(mapData) {
this.showMap = false
// locationGhosts()
// var latng = mapData.latng.split(',')
this.address_info.address_latitude = mapData.latlng.lat
this.address_info.address_longitude = mapData.latlng.lng
var reg = /.+?(省|市|自治區|自治州|縣|區)/g
var areaArr = mapData.poiaddress.match(reg) || [] // 匹配省市區,生成數組
this.address_info.area_info = areaArr.join(' ')
// 如果是直轄市,數組2需要補充一個
if (areaArr.length < 3 && areaArr[0].indexOf('香港') === -1) {
if (areaArr[0].indexOf('省')) {
areaArr.push(areaArr[1])
} else if (areaArr[0].indexOf('市')) {
// 直轄市處理
areaArr.unshift(areaArr[0])
}
}
// 遞歸,獲取對應的省市區ID
let areaIds = this.locationGhosts(this.area_list, areaArr, 0)
this.address_info.province_id = areaIds[0] // 存儲城市ID
this.address_info.city_id = areaIds[1] // 存儲城市ID
this.address_info.area_id = areaIds[2] // 存儲區域ID
this.address_info.area_info_detail = mapData.poiname // 存儲地圖選擇的地址名稱
this.address_info.address_detail = mapData.poiname // 存儲地圖選擇的地址名稱
},
/**
* 遞歸方法,獲取城市ID等
* @param {Array} list 數據庫中的地址列表(每次循環都會拿自己的child來匹配)
* @param {Array} param 需要查找的省市區數組
* @param {Number} level 當前遍歷的深度
* @param {Array} area_ids 當前已遍歷找到的省市區ID數組
* @return 對應的ID數組
*/
locationGhosts(list, param, level = 0, areaIds = []) {
let child = []
param[level] && list.some(item => {
if (param[level].indexOf(item.area_name) !== -1) {
areaIds[level] = item.area_id // 存儲ID,已經找到一個
child = item.child
return true
}
})
!param[level] && (areaIds[level] = 0) // 不存在默認給個0
// 判斷不要改三目運算符,詳情查看尾遞歸相關描述
if (level === 2) {
return areaIds
} else {
return this.locationGhosts(child, param, ++level, areaIds)
}
}
}
}
</script>
思路和之前的文章是一樣的,這次主要是把代碼貼出來,更加完善了一下這個組件