腾讯地图选择地址进阶版(二)

使用腾讯地图的地图组件,获取用户经纬度和当前地址

之前也写过一篇 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>

在这里插入图片描述

思路和之前的文章是一样的,这次主要是把代码贴出来,更加完善了一下这个组件

Logo

前往低代码交流专区

更多推荐