1.登录腾讯地图位置服务进入控制台
- 申请腾讯地图开发者
 - 进入控制台申请自己的key
 
腾讯位置服务 - 立足生态,连接未来

2.进入vue项目的public文件下的index.html
引入腾讯资源包,并把申请的key填入
<script src="https://map.qq.com/api/js?v=2.exp&key=你的key"></script>

3.创建地图容器
<div id="map" style="width:450px;height:200px;"></div>
4.初始化地图、设置标记点并开启拖拽监听
import { reactive, toRefs, getCurrentInstance, Transition, watch } from 'vue';
export default {
    setup() {
        const {proxy} = getCurrentInstance(); // proxy想当于vue2的this
        let data = reactive({
            lng: 116.40396298757886,
            lat: 39.91511908708907,
            map: null,
            searchResults: [], // 存储搜索结果
            marker: [],
            locations: "",
            drapClik: true,
            showDrap: false,
        });
        const methods = {
            // 初始化地图
            initMap: function () {
                //定义地图中心点坐标
                let center = new qq.maps.LatLng(data.lat, data.lng);
                var myOptions = {
                    zoom: 17,
                    center: center,
                    mapTypeId: qq.maps.MapTypeId.ROADMAP,
                };
                data.map = new qq.maps.Map(document.getElementById("map"), myOptions);
                // 设置标记点
                data.marker = new qq.maps.Marker({
                    position: center,
                    map: data.map,
                });
                // 监听标记点拖拽事件
                data.marker.setDraggable(true);
                qq.maps.event.addListener(data.marker, "dragend", function (e) {
                    // 监听标记拖动
                    var latLng = data.marker.getPosition();
                    data.map.setCenter(latLng);
                    let lats = latLng.lat.toFixed(6);
                    let lng = latLng.lng.toFixed(6);
                    data.locations = `${lats},${lng}`;
                    methods.filteredResults();
                });
            },
        }
        proxy.$nextTick(()=>{
            methods.initMap();
        })
    }
}
 
5.拖拽标记点获取点位信息,进行逆地址解析
-  
前提:为解决跨域需要使用vue-jsonp来联调腾讯地图服务端接口
 - WebService API官网:WebService API | 腾讯位置服务
 - 安装vue-jsonp
 
npm安装: npm i vue-jsonp -S
yarn安装: yarn add vue-jsonp
6.引入入vue-jsonp并联调逆地址解析
import { jsonp } from "vue-jsonp";             
            // 逆地址解析
            filteredResults: function () {
                jsonp("https://apis.map.qq.com/ws/geocoder/v1", {
                key: "",
                location: '',
                output: "jsonp", // output必须jsonp   不然会超时
                })
                .then((res) => {
                    if (res.status == 0) {
                        // 通过地址得到经纬度
                        data.warehouseForm.search_address = res.result.address;
                        let center = new qq.maps.LatLng(
                            res.result.location.lat,
                            res.result.location.lng
                        );
                        data.map.panTo(center); // 重新设置地图中心点
                        data.lng = res.result.location.lng;
                        data.lat = res.result.location.lat;
                        data.warehouseForm.longitude = data.lng;
                        data.warehouseForm.latitude = data.lat;
                        methods.focus();
                        methods.suggestion();
                    } else {
                        proxy.$messages.error(res.message);
                        data.searchResults = [];
                    }
                })
                .catch(() => {
                    // search_btn.value = false
                    data.searchResults = [];
                });
            }, 
7.关键词搜索
            // 关键词搜索
            suggestion: function () {
                jsonp("https://apis.map.qq.com/ws/place/v1/suggestion", {
                key: "",
                keyword: '',
                output: "jsonp", // output必须jsonp   不然会超时
                })
                .then((res) => {
                    if (res.status == 0) {
                        data.searchResults = res.data.map(item => ({value: item.location ,label: `${item.title} ${item.address}`}));
                    } else {
                        data.searchResults = [];
                        proxy.$messages.error(res.message);
                    }
                })
                .catch(() => {
                    data.searchResults = [];
                });
            }, 
8.封装AutoComplete
由于使用ant-design的AutoComplete自动完成组件出现报错并不知原因选择自己简单封装
<template>
    <div class='auto-complete' @mouseenter="mouseenter" @mouseleave="mouseleave">
        <PerfectScrollbar class="scrollbar">
                <ul v-show="list.length > 0">
                    <li v-for="(item,index) in list" :key="index" @click="onSelect(item)">
                        <a-tooltip>
                            <template #title>
                                <span>{{item.label}}</span>
                            </template>
                            <span>
                                {{ item.label }}
                            </span>
                        </a-tooltip>
                    </li>
                </ul>
        </PerfectScrollbar>
    </div>
</template>
<script>
export default {
    props: {
        list: {
            type: Array,
            required: true
        }
    },
    setup(props, context) {
        const methods = {
            onSelect : function(item) {
                context.emit('onSelect',item)
            },
            mouseenter () {
                context.emit('mouseenter')
            },
            mouseleave () {
                context.emit('mouseleave')
            }
        }
        return {
            ...methods
        }
    }
 };
</script>
<style lang='less'>
    .auto-complete {
        width: 100%;
        position: absolute;
        top: 32px;
        left: 0;
        background: #fff;
        max-height: 200px;
        z-index: 10;
        .scrollbar {
            width: 100%;
            max-height: 200px;
        }
        ul,li {
            padding: 0;
            margin: 0;
            box-sizing: border-box;
        }
        li {
            width: 100%;
            height: 30px;
            line-height: 30px;
            list-style: none;
            padding: 0 10px;
            cursor: pointer;
            overflow: hidden;//(文字长度超出限定宽度,则隐藏超出的内容)
            white-space: nowrap;//(设置文字在一行显示,不能换行)
            text-overflow: ellipsis;//(规定当文本溢出时,显示省略符号来代表被修剪的文本)
        }
        li:hover {
           background: #e9e9e9; 
        }
    }
</style>
 
完整代码 :
<template>
  <div class="home">
    <div class="search">
      <input
        type="text"
        v-model="keyword"
        @focus="focus"
        @blur="blur"
        placeholder="搜索"
        @keydown.enter="suggestion"
        style="width: 400px; height: 30px"
      />
      <auto-complete
        class="auto-complete"
        v-show="showDrap"
        :list="searchResults"
        @onSelect="onSelect"
        @mouseenter="enter"
        @mouseleave="leave"
      ></auto-complete>
    </div>
    <div id="map" style="width: 750px; height: 400px; background: pink"></div>
  </div>
</template>
<script>
import { reactive, toRefs, getCurrentInstance, Transition, watch } from 'vue';
import { jsonp } from "vue-jsonp"; // npm i vue-jsonp -S
import autoComplete from "@/components/autoComplete.vue";
export default {
    setup() {
        const {proxy} = getCurrentInstance(); // proxy想当于vue2的this
        let data = reactive({
            lng: 116.40396298757886,
            lat: 39.91511908708907,
            map: null,
            searchResults: [], // 存储搜索结果
            marker: [],
            locations: "",
            drapClik: true,
            showDrap: false,
        });
        const methods = {
            // 初始化地图
            initMap: function () {
                //定义地图中心点坐标
                let center = new qq.maps.LatLng(data.lat, data.lng);
                var myOptions = {
                    zoom: 17,
                    center: center,
                    mapTypeId: qq.maps.MapTypeId.ROADMAP,
                };
                data.map = new qq.maps.Map(document.getElementById("map"), myOptions);
                // 设置标记点
                data.marker = new qq.maps.Marker({
                    position: center,
                    map: data.map,
                });
                // 监听标记点拖拽事件
                data.marker.setDraggable(true);
                qq.maps.event.addListener(data.marker, "dragend", function (e) {
                    // 监听标记拖动
                    var latLng = data.marker.getPosition();
                    data.map.setCenter(latLng);
                    let lats = latLng.lat.toFixed(6);
                    let lng = latLng.lng.toFixed(6);
                    data.locations = `${lats},${lng}`;
                    methods.filteredResults();
                });
              },
        // 逆地址解析
        filteredResults: function () {
        jsonp("https://apis.map.qq.com/ws/geocoder/v1", {
          key: "YVOBZ-GIFEX-I3A4E-74VU3-DM7MJ-DQFLX",
          location: data.locations,
          output: "jsonp", // output必须jsonp   不然会超时
        })
          .then((res) => {
            console.log(res);
            if (res.status == 0) {
              // 通过地址得到经纬度
              data.keyword = res.result.address;
              let center = new qq.maps.LatLng(
                res.result.location.lat,
                res.result.location.lng
              );
              data.map.panTo(center); // 重新设置地图中心点
              data.lng = res.result.location.lng;
              data.lat = res.result.location.lat;
              data.longitude = data.lng;
              data.latitude = data.lat;
              methods.focus();
              methods.suggestion();
            } else {
              proxy.$messages.error(res.message);
              data.searchResults = [];
            }
          })
          .catch(() => {
            // search_btn.value = false
            data.searchResults = [];
          });
      },
      // 关键词搜索
      suggestion: function () {
        console.log(1111);
        jsonp("https://apis.map.qq.com/ws/place/v1/suggestion", {
          key: "YVOBZ-GIFEX-I3A4E-74VU3-DM7MJ-DQFLX",
          keyword: data.keyword,
          output: "jsonp", // output必须jsonp   不然会超时
        })
          .then((res) => {
            console.log(res);
            if (res.status == 0) {
              data.searchResults = res.data.map((item) => ({
                value: item.location,
                label: `${item.title} ${item.address}`,
              }));
            } else {
              data.searchResults = [];
              proxy.$messages.error(res.message);
            }
          })
          .catch(() => {
            data.searchResults = [];
          });
      },
      onSearch: debounceInput(() => {
        data.searchResults = [];
        methods.suggestion();
      }, 500),
      onSelect: function (item) {
        data.drapClik = true;
        data.showDrap = false;
        data.keyword = item.label;
        methods.setOptions(item);
        data.lng = item.value.lng;
        data.lat = item.value.lat;
        data.longitude = data.lng;
        data.latitude = data.lat;
      },
      setOptions(item) {
        // 通过地址得到经纬度
        let center = new qq.maps.LatLng(item.value.lat, item.value.lng);
        data.map.panTo(center); // 重新设置地图中心点
        // 更新标记的位置
        data.marker.setPosition(
          new qq.maps.LatLng(item.value.lat, item.value.lng)
        );
      },
      focus() {
        data.showDrap = true;
      },
      enter() {
        data.drapClik = false;
      },
      leave() {
        data.drapClik = true;
      },
      blur() {
        let timer = setInterval(() => {
          if (data.drapClik) {
            data.showDrap = false;
            clearInterval(timer);
            data.drapClik = true;
          }
        }, 80);
      },
        }
        proxy.$nextTick(()=>{
            methods.initMap();
        })
    },
    components: {
        autoComplete,
    },
}
</script>
 
效果:

















