vue3 封装高德地图通用组件

  • 页面效果

  

  • 下载安装地图依赖
"dependencies": {
    "@element-plus/icons-vue": "1.1.4",
    "@vuemap/vue-amap": "^1.1.3", // --------------- 地图依赖
    "axios": "0.26.1",
    "echarts": "5.3.2",
    "element-plus": "2.1.8",
    "file-saver": "2.0.5",
    "fuse.js": "6.5.3",
    "js-cookie": "3.0.1",
    "jsencrypt": "3.2.1",
    "nprogress": "0.2.0",
    "vue": "3.2.31",
    "vue-cropper": "1.0.3",
    "vue-router": "4.0.14",
    "vuex": "4.0.2"
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "2.3.1",
    "@vue/compiler-sfc": "3.2.31",
    "@vuemap/unplugin-resolver": "^1.0.3", // --------------- 地图依赖
    "sass": "1.50.0",
    "unplugin-auto-import": "^0.7.1",
    "unplugin-vue-components": "^0.19.5",
    "vite": "2.6.14",
    "vite-plugin-compression": "0.5.1",
    "vite-plugin-svg-icons": "1.0.5",
    "vite-plugin-vue-setup-extend": "0.4.0"
  }
  • 在mian.js中注册引入
import VueAMap from '@/components/aMap/aMap'
app.use(VueAMap)
  • 封装地图组件

js文件内容

import VueAMap, {initAMapApiLoader} from '@vuemap/vue-amap'
import '@vuemap/vue-amap/dist/style.css'

window._AMapSecurityConfig = {
    securityJsCode: 'b2f50ad82bdd6c8a7aaf2bba746f1578',
}
initAMapApiLoader({
    key: '80192ad1586347ee8733bab8ee4388a8',  //备用测试key e1dedc6bdd765d46693986ff7ff969f4
    version: "2.0",   // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
    // 需要使用的的插件列表,如比例尺'AMap.Scale'等
    plugin: [
        'AMap.Autocomplete', // 输入提示插件
        'AMap.PlaceSearch', // POI搜索插件
        'AMap.Scale', // 右下角缩略图插件 比例尺
        'AMap.OverView', // 地图鹰眼插件
        'AMap.ToolBar', // 地图工具条
        'AMap.Geolocation', // 定位控件,用来获取和展示用户主机所在的经纬度位置
        'AMap.Geocoder',
        'AMap.MapType',
    ],
    AMapUI: {             // 是否加载 AMapUI,缺省不加载
        "version": '1.1',   // AMapUI 版本
        "plugins": ['overlay/SimpleMarker'],       // 需要加载的 AMapUI ui插件
    },
})
// 捕获未知错误 并重载页面
window.addEventListener('error', (e) => {
    console.log(e, 'error')
}, true)
export default VueAMap

 index.vue页面内容

<template>
    <div class="aMapMain">
        <div v-if="isDisplayAMap">
            <div class="aMap">
                <el-amap ref="mapRef" :min-zoom="8" :max-zoom="22" :center="center" :zoom="zoom" @init="initMap">
                    <el-amap-search-box @select="selectPoi" @choose="selectPoi" v-if="isShowAMap"/>
                    <el-amap-marker :position="componentMarker.position" :content="componentMarker.content"/>
                </el-amap>
            </div>
            <div class="aMapAddress">
                <p>
                    <span>地址:</span>
                    <span>{
   
   { toParentsMapInfo.detailedAddress }}</span>
                </p>
            </div>
        </div>
        <div v-else class="isDisplayAMap">
            <el-amap ref="mapRef" :min-zoom="8" :max-zoom="22" :center="center" :zoom="zoom" @init="initMap">
                <el-amap-search-box @select="selectPoi" @choose="selectPoi" v-if="isShowAMap"/>
                <el-amap-marker :position="componentMarker.position" :content="componentMarker.content"/>
            </el-amap>
        </div>
    </div>
</template>

<script setup name="AMap">
    import {Plus, Delete} from '@element-plus/icons-vue'
    import {toRefs} from '@vueuse/shared'
    import {reactive, ref} from '@vue/reactivity'
    import {defineProps, getCurrentInstance} from '@vue/runtime-core'

    const {proxy} = getCurrentInstance()
    const props = defineProps({
        toParentsMap: {
            type: Object, // 父组件传来的默认数据
            default: {}
        },
        isShowAMap: {
            type: Boolean, // 控制是否展示搜索框
            default: null
        },
        isDisplayAMap: {
            type: Boolean, // 控制是否展示地图试图
            default: true
        },
    })
    const emit = defineEmits(['mapData'])
    const zoom = ref(16)
    const center = ref([
        props.toParentsMap.lng || 113.887902,
        props.toParentsMap.lat || 22.554732
    ])
    const componentMarker = ref({
        position: [
            props.toParentsMap.lng || 113.887902,
            props.toParentsMap.lat || 22.554732
        ],
        visible: true,
        draggable: false
    })
    const toParentsMapInfo = ref({})

    /** 接受父组件传值进行赋值 初始化地图数据*/
    function initMapInfo() {
        console.log(center.value)
        toParentsMapInfo.value = props.toParentsMap

    }

    /** 初始化地图*/
    function initMap(e) {
        console.log(props.isShowAMap)
    }

    /** 选取定位地图*/
    function selectPoi(e) {
        let poi = e.poi
        if (poi.address.length > 0 && poi.location != undefined &&
            poi.location != null && poi.location != '') {
            let position = [e.poi.location.lng, e.poi.location.lat]
            center.value = position
            componentMarker.value.position = position
            toParentsMapInfo.value = {
                id: poi.id,
                lng: poi.location.lng, //经度
                lat: poi.location.lat, //纬度
                districtCode: poi.adcode, //区编码
                //address: poi.address, //地址
                //district: poi.district, //省名称 市名称 区名称
                //name: poi.name, //查询地址
                province: '', //省地址
                city: '', //市地址
                zone: '', //区地址
                detailedAddress: '' //详细地址
            }

            let reg = /.+?(省|市|自治区|自治州|盟|旗|县|区)/g // 截取地图地址
            let detailedAddress = poi.district + poi.address + poi.name
            let districtList = detailedAddress.match(reg)
            if (districtList.length < 3) {
                toParentsMapInfo.value.city = districtList[0]
                toParentsMapInfo.value.zone = districtList[1]
            } else {
                toParentsMapInfo.value.city = districtList[1]
                toParentsMapInfo.value.zone = districtList[2]
            }
            toParentsMapInfo.value.province = districtList[0]
            toParentsMapInfo.value.detailedAddress = detailedAddress

            console.log(toParentsMapInfo.value)
            emit('mapData', toParentsMapInfo.value) // 传值到父组件
        } else {
            proxy.$modal.msgWarning('输入的位置定位失败, 请输入详细位置进行定位!')
        }
    }

    initMapInfo()
</script>

<style lang="scss">
    .amap-sug-result {
        z-index: 2099;
    }

    .amap-copyright {
        height: 24px;
    }

    .el-vue-search-box-container,
    .el-vue-search-box-container input {
        height: 29px;
        border-radius: 8px;
    }

    .aMapMain {
        width: 100%;

        .aMap {
            width: 100%;
            height: 229px;
        }

        .aMapAddress {
            text-align: left;

            p {
                margin-top: 5px;
                margin-bottom: 0;
            }
        }

        .isDisplayAMap {
            width: 100%;
            height: 36px;

            .el-vue-amap {
                display: none;
            }

            .el-vue-search-box-container {
                position: initial;
                width: 100%;
            }
        }
    }

    .el-vue-search-box-container {
        border: 1px solid #e2e2e2;
        height: 36px;
        box-shadow: none;
    }
</style>
  • 父组件引入
<!-- 模拟数据 
const toParentsMap = ref({
        city: "深圳市",
        detailedAddress: "",
        districtCode: "440304",
        id: "B02F37TV2J",
        lat: null,
        lng: null,
        province: "广东省",
        zone: "宝安区",
    }) -->

<el-form-item label="集结地点">
   <span>搜索框和地图试图都展示</span>
   <aMap :toParentsMap="toParentsMap" :isShowAMap="true"></aMap>

   <span>只展示搜索框 不展示地图试图</span>
   <aMap :toParentsMap="toParentsMap" :isShowAMap="true" :isDisplayAMap="false"></aMap>
</el-form-item>


import aMap from '@/components/aMap/index' //引入封装好的组件

猜你喜欢

转载自blog.csdn.net/lovexiuwei/article/details/125426412