vue3使用腾讯地图(‘关键词搜索、逆地址解析‘)

news2024/9/29 7:18:39

 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>

效果:

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/737558.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

文心一言 VS 讯飞星火 VS chatgpt (57)-- 算法导论6.4 1题

文心一言 VS 讯飞星火 VS chatgpt &#xff08;57&#xff09;-- 算法导论6.4 1题 一、参照图 6-4 的方法&#xff0c;说明 HEAPSORT 在数组 A(5&#xff0c;13&#xff0c;2&#xff0c;25&#xff0c;7&#xff0c;17&#xff0c;20&#xff0c;8&#xff0c;4)上的操作过程…

怎么修复损坏的视频文件?视频文件修复办法分享!

随着科技的不断发展&#xff0c;我们的生活中已经离不开各种类型的视频文件。因为各式各样的原因&#xff0c;有时候我们的视频文件可能会损坏。 而损坏的视频文件通常是无法正常播放&#xff0c;这无疑会给我们的生活和工作造成极大的困扰。那么&#xff0c;怎么修复损坏的视…

【Linux学习】记录下Linux的常用基本指令~

1、Linux是一个操作系统&#xff0c;和windows是“并列”关系。Linux已经成为"世界第一大操作系统"。 2、Linux这种使用命令的方式比图形化界面的好处&#xff1f; &#xff08;1&#xff09;节省系统资源&#xff1a;运行图形化界面需要让系统付出一些额外开销&am…

stm32(时钟和中断事件知识点)

一、复位和时钟控制&#xff08;RCC&#xff09; 复位 系统复位 当发生以下任一事件时&#xff0c;产生一个系统复位&#xff1a; 1. NRST引脚上的低电平(外部复位) 2. 窗口看门狗计数终止(WWDG复位) 3. 独立看门狗计数终止(IWDG复位) 4. 软件复位(SW复位) 5. 低功耗管…

软件为什么需要进行应急演练脚本?

软件为什么需要进行应急演练脚本&#xff1f;在当今互联网时代&#xff0c;安全问题愈加突出&#xff0c;不断有新的网络攻击方式不断涌现。针对软件系统的安全漏洞和攻击活动不断增加&#xff0c;软件应急演练变得尤为重要。 首先&#xff0c;应急演练可以帮助软件团队建立应急…

C++11可变参数模板,lambda表达式,包装器

目录 可变参数模板 lambda表达式 问题的引入 lambda表达式语法 捕捉列表的使用 函数对象和lambda表达式 function包装器 可变参数模板 C11的新特性可变参数模板能够让您创建可以接受可变参数的函数模板和类模板&#xff0c;相比C98/&#xff0c;类模版和函数模版中只能…

基于redis实现延时队列(一)

背景 最近项目中需要对一条数据&#xff0c;在半小时候更改其状态&#xff0c;类似于提交商城订单半小时后未支付的订单需要更改为超时状态&#xff0c;当然这个解决方案有很多&#xff0c;最好的解决方案是用MQ的死信队列&#xff1b;但由于项目中没有引入MQ&#xff0c;故本…

PMP-质量管理的重要性

本篇文章主要是方便从事于项目管理的“初学者”们了解质量管理的重要性&#xff01;&#xff01;&#xff01; 一、什么是质量管理 项目质量管理包括把组织的质量政策应用于规划、管理、控制项目和产品质量要求&#xff0c;以满足相关方目标的各个过程。此外&#xff0c;项目质…

Latex公式炫酷技巧

最近看到一个炫酷的latex公式用法&#xff0c;特意在此记录一下 效果如下 latex代码如下 \begin{equation}\mathcal{L}_{mot}^{\textcolor{magenta}{\bullet}} \frac{1}{\sum_{i1}^{N}{s_i^l}}\sum_{i1}^{N}\Big\Vert{s}^{l}_i(\mathbf{\hat{f}}_i-\mathbf{f}^{fg}_i)\Big…

网络安全系统教程+学习路线

一、什么是网络安全 网络安全可以基于攻击和防御视角来分类&#xff0c;我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术&#xff0c;而“蓝队”、“安全运营”、“安全运维”则研究防御技术。 无论网络、Web、移动、桌面、云等哪个领域&#xff0c;都有攻与防两面…

【MySQL系列】表的学习及基本操作

「前言」文章内容大致是数据库表的基本操作 「归属专栏」MySQL 「主页链接」个人主页 「笔者」枫叶先生(fy) 「枫叶先生有点文青病」「句子分享」 人生当苦无妨&#xff0c;良人当归即好。 ——烽火戏诸侯《雪中悍刀行》 目录 一、创建表二、修改表三、 删除表 一、创建表 创建…

组合模式的例子

// 组合模式的接口 public interface AccessDecisionVoter {// 投票结果的常量int ACCESS_GRANTED 1;int ACCESS_ABSTAIN 0;int ACCESS_DENIED -1;// 投票方法&#xff0c;根据用户和请求判断是否授权int vote(User user, Request request); }// 组合模式的叶子节点&#xf…

Android中system/bin/Input命令 -- Android12

IMS:Android中Input命令--Android12 1、Android12 Input命令更新1.1 shell脚本1.2 InputShellCommand#onCommand 命令解析 2、Input相关命令参数2.1 text2.2 keyevent2.3 tap2.4 swipe2.5 draganddrop2.6 press2.7 roll2.8 motionevent2.9 keycombination2.10 默认handleDefaul…

2023 WAIC图技术激活数据要素论坛圆满召开!

7月6日&#xff0c;以“智联世界 生成未来”为主题的2023世界人工智能大会&#xff08;WAIC 2023&#xff09;在上海隆重开幕。作为大会唯一的图技术论坛&#xff0c;“图技术激活数据要素论坛”也如期举行。 论坛现场&#xff0c;学术界专家学者、头部银行代表、产业界大咖齐聚…

二分图博弈(知识总结+例题)

思路来源 gzchenben的ppt 算法学习笔记(74): 二分图博弈 - 知乎 https://www.cnblogs.com/Zeardoe/p/16534557.html 知识点总结 以下部分摘自知乎&#xff1a;算法学习笔记(74): 二分图博弈 - 知乎 二分图博弈模型 给出一张二分图和起始点 H &#xff0c; A和B轮流操作…

Endnotes引用

准备不用zetro了&#xff0c;主要学校endnotes免费 该说不说&#xff0c;zetro拖入pdf直接识别并导入的功能是真的好用&#xff0c;添加备注也方便 可惜文献太多放不下了&#xff0c;扩容要加钱。 啧。算了算了。 这里主要介绍Endnotes中的文献怎么在word内引用&#xff0c…

SpringBoot 插件化开发模式,强烈推荐!

一、前言 插件化开发模式正在很多编程语言或技术框架中得以广泛的应用实践&#xff0c;比如大家熟悉的jenkins&#xff0c;docker可视化管理平台rancher&#xff0c;以及日常编码使用的编辑器idea&#xff0c;vscode等&#xff0c;随处可见的带有热插拔功能的插件&#xff0c;…

BitLocker 驱动器加密管理

为了有效地保护数字数据&#xff0c;应对其进行加密&#xff0c;以便只有授权用户才能访问。BitLocker 是某些 Windows 操作系统上可用的本机加密工具&#xff0c;可以为个人用户轻松加密Windows计算机。 什么是 BitLocker 加密 BitLocker 加密是 Windows 操作系统的内置安全…

STM32实现气压传感器测量(BMP180)

目录 0.接线设计 1.功能描述 2.四种方式实现大气压采集 3.模块选择 4.编程环境 5.模块主要参数 6.代码实现 1&#xff09;标准库模拟IIC实现气压值采集 2&#xff09;标准库硬件IIC实现气压值采集 3&#xff09;HAL库模拟IIC实现气压值采集 4&#xff09;HAL库硬件IIC实…

分享一次腾讯云轻量应用服务器被攻击

腾讯云轻量应用服务器&#xff0c;centOS。在上面装了redis、rabbit mq等服务&#xff0c;开着端口&#xff0c;结果被入侵了。 发现问题是通过腾讯云发来的邮件&#xff0c; 首先进到主机安全控制台&#xff0c;左侧这里进主机列表 然后可以看到自己的主机情况&#xff0c;防…