vue项目中使用高德地图/腾讯地图

需求:

1、点击编辑图标能打开对弹窗选值地址。

2、店铺经纬度为空时,默认定位到浏览器当前定位。有值时,定位到提供的经纬度。

3、2种方法选择地址:输入关键词可以搜索地址,移动定位图标也可以选择地址。

4、地图的key由客户提供,后端返回,不能写死。

高德地图

一、使用npm方式安装高德地图

npm i @amap/amap-jsapi-loader --save

二、页面中引入并使用

<template>
  <div @click="showMapBtn1" class="addressBox">
    <span :class="{ 'mr-8px': detailData.storeAddress }">{{ detailData.storeAddress }}</span>
    <img class="imgs" src="/src/assets/images/editAddress.png" style="width: 16px;height: 16px;" />
  </div>

  <a-modal v-model:visible="showMap1" width="50%" title="地图选点" @ok="setMap1" style="top: 12vh;">
    <div class="gdMapWrapper">
      <div id="gdMapContainer"
        style=" height: 222px;width: 100%;border: none;border-radius: 8px;margin-bottom: 24px; background-color: #f9fafb; display: flex;justify-content: center; align-items: center;">
        <a-spin v-if="isLoadingMap" :indicator="indicator" />
      </div>
      <div class="searchContainer">
        <a-input class="searchMapInput" v-model:value="word" placeholder="请输入详细地址" @change="searchMap"></a-input>
        <div class="poiListContainer" v-if="poiList.length > 0">
          <div class="poiListContainerItem" v-for="(item, index) in poiList" :key="item.id"
            @click="selectPoi(item, index)">
            <div class="left">
              <div class="row1">{{ item.name }}</div>
              <div class="row2">{{ item.address }}</div>
            </div>
            <div class="right">
              <div :class="{ 'active': activeId == item.id }">
                <img v-if="activeId == item.id" :src="img2" />
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </a-modal>
</template>

<script>
  import AMapLoader from "@amap/amap-jsapi-loader";
  import { Button,  message,  Modal,  Spin} from 'ant-design-vue';
  import { getAutonaviKey } from '/@/api/merchant';
  export default defineComponent({
    name: 'MerchantDetail',
    components: {
      Button,
      AModal: Modal,
      ASpin: Spin,
    },
    setup() {
      // 高德地图相关-------------------------
      let keyInfo = { secret: '', key: '' } //高德key
      const word = ref() //搜索关键词
      const cityCode = ref() //用于地图搜索周边区域
      let lngLatArr = [] //当前店铺的经纬度
      let poiList = ref([]) //搜索地址结果列表
      const isLoadingMap = ref(false)
      const indicator = h(LoadingOutlined, { //loading效果
        style: {
          fontSize: '36px',
        },
        spin: true,
      });

      // 初始化地图
      async function initMap(data) {
        //获取地图的key
        keyInfo = await getAutonaviKey();
        window._AMapSecurityConfig = {
          securityJsCode: keyInfo.secret,
        }

        // 先判断店铺是否有已存入地址
        if (Number(data.longitude) !== 0 && Number(data.latitude) !== 0) {
          lngLatArr = [+data.longitude, +data.latitude]
        } else {
          lngLatArr = []
        }

        AMapLoader.load({
          key: keyInfo.key, // 申请好的Web端开发者Key,首次调用 load 时必填
          version: "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
          // plugins:[''], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
        }).then(async (AMap) => {
          // 没有地址,默认浏览器当前定位
          function getCurrentPosition() {
            return new Promise((resolve, reject) => {
              var options = {
                'showButton': false,//是否显示定位按钮
                'position': 'LB',//定位按钮的位置
                /* LT LB RT RB */
                'offset': [10, 20],//定位按钮距离对应角落的距离
                'showMarker': false,//是否显示定位点
                'markerOptions': {//自定义定位点样式,同Marker的Options
                  'offset': new AMap.Pixel(-18, -36),
                  'content': '<img src="https://a.amap.com/jsapi_demos/static/resource/img/user.png" style="width:36px;height:36px"/>'
                },
                'showCircle': false,//是否显示定位精度圈
                'circleOptions': {//定位精度圈的样式
                  'strokeColor': '#0093FF',
                  'noSelect': false,
                  'strokeOpacity': 0.5,
                  'strokeWeight': 1,
                  'fillColor': '#02B0FF',
                  'fillOpacity': 0.25
                }
              }
              isLoadingMap.value = true
              // 地图定位
              AMap.plugin(["AMap.Geolocation"], function () {
                var geolocation = new AMap.Geolocation(options);
                geolocation.getCurrentPosition((status, result) => {
                  if (status == 'complete') {
                    lngLatArr = [+result.position.lng, +result.position.lat]
                    isLoadingMap.value = false
                    resolve(true)
                  } else {
                    isLoadingMap.value = false
                    lngLatArr = [116.397755, 39.903179] //定位失败,默认北京天安门
                    resolve(true)
                  }
                })
              });
            })
          }

          if (lngLatArr.length == 0) {
            await getCurrentPosition()
          }

          var marker, map = new AMap.Map("gdMapContainer", {
            viewMode: "3D",
            resizeEnable: true,
            center: lngLatArr,
            zoom: 16,
          });

          // 实例化点标记
          function addMarker() {
            if (!marker) {
              marker = new AMap.Marker({
                // icon: "//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png",
                icon: '/src/assets/images/marker.png',
                position: lngLatArr,
                offset: new AMap.Pixel(-13, -30),
                draggable: true,
              });
              marker.setMap(map);
            }
          }
          addMarker()

          //拖动坐标获取新坐标
          marker.on('dragend', function () {
            let position = [marker.getPosition().lng, marker.getPosition().lat] //位置的经纬度 
            new AMap.plugin("AMap.Geocoder", () => {
              const geocoder = new AMap.Geocoder({
                // city: "028" //指定进行编码查询的城市,支持传入城市名、adcode 和 citycode
              });
              geocoder.getAddress(position, (status, result) => {
                if (status === "complete" && result.info === "OK") {
                  word.value = result.regeocode.formattedAddress
                  cityCode.value = result.regeocode.addressComponent.citycode
                  searchMap()
                }
              });
            });
          })
        })
      }

      // 搜索地址
      function searchMap() {
        AMapLoader.load({
          key: keyInfo.key,
          version: '2.0'
        }).then((AMap) => {
          var keywords = word.value
          AMap.plugin(['AMap.AutoComplete', 'AMap.PlaceSearch'], function () {
            var autoOption = {
              // city: cityCode.value ?? '020', //默认搜索广州
              pageSize: 99,
              pageIndex: 1,
              datatype: 'poi',
              extensions: "all",
              citylimit: false //是否限制只搜索当前市的地址
            }
            var placeSearch = new AMap.PlaceSearch(autoOption)
            placeSearch.search(keywords, function (status, result) {
              if (result.info == 'OK') {
                poiList.value = result.poiList.pois
              }
            })
          })
        })
      }

      // 移动修改定位点
      function editMarker(arr) {
        AMapLoader.load({
          key: keyInfo.key,
          version: '2.0'
        }).then((AMap) => {
          var marker, map = new AMap.Map("gdMapContainer", {
            viewMode: "3D",
            resizeEnable: true,
            center: arr,
            zoom: 16,
          });

          // 实例化点标记
          function addMarker() {
            if (!marker) {
              marker = new AMap.Marker({
                // icon: "//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png",
                icon: "/src/assets/images/marker.png",
                position: arr,
                offset: new AMap.Pixel(-13, -30),
                draggable: true,
              });
              marker.setMap(map);
            }
          }
          addMarker()

          marker.on('dragend', function () {//拖动坐标获取新坐标
            let position = [marker.getPosition().lng, marker.getPosition().lat] //位置的经纬度 
            new AMap.plugin("AMap.Geocoder", () => {
              const geocoder = new AMap.Geocoder({
                // city: "028" //指定进行编码查询的城市,支持传入城市名、adcode 和 citycode
              });
              geocoder.getAddress(position, (status, result) => {
                if (status === "complete" && result.info === "OK") {
                  cityCode.value = result.regeocode.addressComponent.citycode
                  word.value = result.regeocode.formattedAddress
                  searchMap()
                }
              });
            });
          })
        })
      }

      // 下拉选择地址
      const activeId = ref('')
      function selectPoi(item, index) {
        activeId.value = item.id
        poiList.value.map(el => {
          if (el.id == item.id) {
            searchMapInfo.value = {
              latitude: el.location.lat,
              longitude: el.location.lng,
              storeAddress: el.address,
              cityCode: el.citycode
            }
            editMarker([el.location.lng, el.location.lat])
          }
        })
      }

      //更新地址
      function setMap1() {
        if (!searchMapInfo.value.latitude || searchMapInfo.value.longitude == '') {
          message.warning('请选择一个地址');
          return
        }

        let data = {
          id: detailData.value.id,
          ...searchMapInfo.value
        };

        updateStoreAddress(data).then(res => {
          message.success('店铺地址更新成功')
          showMap1.value = false;
          word.value = ''
          poiList.value = []
          getHeaderDetailData();
        })

      }

      function showMapBtn1() {
        mapForm.value = {};
        showMap1.value = true;
        searchMapInfo.value = {};
        initMap(detailData.value)
      }
    }
  })

</script>

腾讯地图

使用iframe来展示地图区域。

腾讯自带搜索栏,地址添加属性search=1。

此处是写死key。

<template>
  <div @click="showMapBtn1" class="addressBox">
    <span :class="{ 'mr-8px': detailData.storeAddress }">{{ detailData.storeAddress }}</span>
    <img class="imgs" src="/src/assets/images/editAddress.png" style="width: 16px;height: 16px;" />
  </div>

  <a-modal v-model:visible="showMap1" width="50%" title="地图选点" @ok="setMap1">
    <iframe width="100%" style="height: 60vh; width: 100%; border: none;" :src="map_src"></iframe>
  </a-modal>
</template>

<script>
  import AMapLoader from "@amap/amap-jsapi-loader";
  import { Button,  message,  Modal,  Spin} from 'ant-design-vue';
  import { getAutonaviKey } from '/@/api/merchant';
  export default defineComponent({
    name: 'eidtMap',
    components: {
      Button,
      AModal: Modal,
      ASpin: Spin,
    },
    setup() {
      // 腾讯地图相关
      let searchMapInfo = ref<any>({})
      window.addEventListener('message', function (event) {
        // 接收位置信息,用户选择确认位置点后选点组件会触发该事件,回传用户的位置信息
        var loc = event.data;
        if (loc && loc.module == 'locationPicker') {//防止其他应用也会向该页面post信息,需判断module是否为'locationPicker'
          searchMapInfo.value = {
            latitude: loc.latlng.lat,
            longitude: loc.latlng.lng,
            storeAddress: loc.poiaddress
          }
        }
      }, false);
      let showMap1 = ref(false);
      let mapForm = ref<any>({});
      let map_src = ref('https://apis.map.qq.com/tools/locpicker?search=1&type=1&key=你的key&referer=你的referer');

      //更新地址
      function setMap1() {
        if (!searchMapInfo.value.latitude || searchMapInfo.value.longitude == '') {
          message.warning('请选择一个地址');
          return
        }

        let data = {
          id: detailData.value.id,
          ...searchMapInfo.value
        };

        updateStoreAddress(data).then(res => {
          message.success('店铺地址更新成功')
          showMap1.value = false;
          word.value = ''
          poiList.value = []
          getHeaderDetailData();
        })

      }

      function showMapBtn1() {
        mapForm.value = {};
        showMap1.value = true;
        searchMapInfo.value = {};
      }
    }
  })

</script>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值