vue 中 使用腾讯地图 (动态引用腾讯地图及使用签名验证)

在这里插入图片描述
在这里插入图片描述

在设置定位的时候使用 腾讯地图 选择地址
在 mounted中引入腾讯地图:
this.website.mapKey 为地图的 key

// 异步加载腾讯地图API
      const script = document.createElement('script');
      script.type = 'text/javascript';
      script.src = 'https://map.qq.com/api/js?v=2.exp&key='+this.website.mapKey+'&callback=init';
      document.body.appendChild(script);
      // 回调函数,初始化地图
      window.init = () => {
        this.initMap();
        this.$nextTick(()=>{
          if(this.map){
            //   // 监听中心点变化事件,更新marker的位置
            this.listener=qq.maps.event.addListener(this.map, 'dragend', ()=>this.centerChanged());
          }
        })
      };

在 destroyed 卸载

 destroyed(){
      let scripts = document.querySelectorAll('script');
      // 遍历所有找到的<script>元素并移除它们
      scripts.forEach((script)=> {
        let src=script.getAttribute('src');
        if(src&&src.indexOf('qq')>=0){
          script.parentNode.removeChild(script);
        }
      });
      qq.maps.event.removeListener(this.listener)
    },

弹框组件代码为:

<template>
  <el-dialog title="设置定位"
             :visible.sync="dialogVisible"
             width="900px"
             :before-close="handleClose"
             :modal-append-to-body="true"
             :append-to-body="true"
             :close-on-click-modal="false"
             v-dialogdrag
             class="common-dialog">
    <div class="clearfix">
      <div class="pull-left near-box">
        <el-input v-model="keyword" @change="changeKeyword">
          <el-button slot="append" icon="el-icon-search" @click="searchNear"></el-button>
        </el-input>
        <ul class="location-list">
          <li v-for="(item,index) in nearList" :key="index" :class="selectedIndex==index?'location-active':''">
            <div @click="handleSelect(item,index)">
              <div class="location-title">{{item.title}}</div>
              <span class="location-address">{{item.address}}</span>
            </div>
          </li>
        </ul>
      </div>
      <div class="pull-right map-box">
        <div id="container"></div>
      </div>
    </div>
    <span slot="footer" class="dialog-footer">
      <el-button @click="handleClose">取 消</el-button>
      <el-button type="primary" @click="submitAction">确 定</el-button>
    </span>
  </el-dialog>
</template>
<script>
  import {mapGetters} from "vuex";
  import {getAddressByLat,searchByKeyword} from '@/api/address'
  export default {
    props:{
      form:{
        type: Object
      }
    },
    data(){
      return {
        selectedIndex:'',
        keyword: '山东省青岛市',
        dialogVisible : true,
        mapZoom: 15,
        pitch: 0,
        addressInfo: this.form,
        mapCenter: {
          adcode: 370203,
          city: "青岛市",
          district: "市北区",
          ip: "111.17.222.181",
          lat: 36.08743,
          lng: 120.37479,
          nation: "中国",
          province: "山东省"
        },
        nearList:[],
        map:null,//地图
        markerLayer:null,
        listener:null
      }
    },
    mounted(){
      if(this.form.lat&&this.form.lng){
        this.mapCenter={
          ...this.form,
          city:this.form.cityName
        };
        this.keyword=this.form.provinceName+this.form.cityName+this.form.areaName+this.form.address.substring(0,64)
      } else if(this.location.lat){
        this.mapCenter = {...this.location};
        if(this.location.province&&this.location.city){
          this.keyword=(this.location.province+this.location.city).substring(0,64)
        }
      }
      // 异步加载腾讯地图API
      const script = document.createElement('script');
      script.type = 'text/javascript';
      script.id = 'qqMap';
      script.name = 'qqMap';
      script.src = 'https://map.qq.com/api/js?v=2.exp&key='+this.website.mapKey+'&callback=init';
      document.body.appendChild(script);
      // 回调函数,初始化地图
      window.init = () => {
        this.initMap();
        this.$nextTick(()=>{
          if(this.map){
            //   // 监听中心点变化事件,更新marker的位置
            this.listener=qq.maps.event.addListener(this.map, 'dragend', ()=>this.centerChanged());
          }
        })
      };
    },
    destroyed(){
      let scripts = document.querySelectorAll('script');
      // 遍历所有找到的<script>元素并移除它们
      scripts.forEach((script)=> {
        let src=script.getAttribute('src');
        if(src&&src.indexOf('qq')>=0){
          script.parentNode.removeChild(script);
        }
      });
      qq.maps.event.removeListener(this.listener)
    },
    computed: {
      ...mapGetters(["location"]),
    },
    methods:{
      //初始化地图
      initMap(){
        let element=document.getElementById('container');
        //定义地图中心点坐标
        let center=new qq.maps.LatLng(this.mapCenter.lat,this.mapCenter.lng);
        //定义map变量,调用 TMap.Map() 构造函数创建地图
        this.map = new qq.maps.Map(element, {
          pitch: this.pitch,
          center: center,//设置地图中心点坐标
          zoom:this.mapZoom,   //设置地图缩放级别
        });
        // 创建一个位于地图中心点的marker
        this.markerLayer = new qq.maps.Marker({
          map: this.map,
          position: center
        });

        if(this.keyword){
          this.getAddressByKeyword( this.mapCenter)
        }
      },
      centerChanged(){
        this.mapCenter=this.map.getCenter();
        this.getLocationByLat()
      },
      //当前选择
      handleSelect(item,index){
        this.selectedIndex=index;
        this.mapCenter={
          ...item,
          lat:item.location.lat,
          lng:item.location.lng,
        };
        this.map.setCenter(new qq.maps.LatLng(item.location.lat,item.location.lng));
        this.markerLayer.setPosition(new qq.maps.LatLng(item.location.lat,item.location.lng))
        // this.getLocationByLat()
      },
      changeKeyword(val){
        this.keyword=val;
      },
      searchNear(){
        this.mapCenter={};
        this.getAddressByKeyword()
      },
      getLocationByLat(){
        getAddressByLat({
          location:`${this.mapCenter.lat},${this.mapCenter.lng}`,
          key:this.website.mapKey,
        }).then(res=>{
          this.keyword=res.result.address;
          this.getAddressByKeyword(res.result)
        })
      },
      //根据关键字查找地址列表
      //https://lbs.qq.com/service/webService/webServiceGuide/webServiceSuggestion
      getAddressByKeyword(latInfo){
        let params={
          keyword:this.keyword,
          region:this.mapCenter.city?this.mapCenter.city:'',
          policy:1,
          page_size:20,
          page_index:1,
          address_format:'short',
          key:this.website.mapKey,
        };
        if(this.mapCenter.lat&&this.mapCenter.lat!=-1&&this.mapCenter.lng&&this.mapCenter.lng!=-1){
          params.location=`${this.mapCenter.lat},${this.mapCenter.lng}`
        }
        searchByKeyword(params).then(res=>{
          this.nearList=res.data;
          let first=res.data&&res.data[0]?res.data[0]:'';
          if(first){
            this.selectedIndex=0;
            if(!params.location){
              let lat=first.location.lat;
              let lng=first.location.lng;
              this.mapCenter={
                ...first,
                lat:lat,
                lng:lng
              };
              this.map.setCenter(new qq.maps.LatLng(lat,lng))
            }

          } else if(latInfo){
            let obj={
              ...latInfo.ad_info,
              ...latInfo.location,
              address:latInfo.address,
              title:latInfo.formatted_addresses&&latInfo.formatted_addresses.recommend?latInfo.formatted_addresses.recommend:latInfo.address
            };
            this.mapCenter=obj;
            this.nearList=[obj];
            this.map.setCenter(new qq.maps.LatLng(this.mapCenter.lat,this.mapCenter.lng))
          }
          this.markerLayer.setPosition(new qq.maps.LatLng(this.mapCenter.lat,this.mapCenter.lng))
        })
      },
      handleClose(){
        this.dialogVisible=false;
        this.$emit('closeDialog',false)
      },
      submitAction(){
        if(!this.keyword){
          this.$message.error('请输入关键字查询/或拖动地图查找');
          return false
        }
        this.$emit('changeMapLocation', this.selectedIndex>=0&&this.nearList[this.selectedIndex]?this.nearList[this.selectedIndex]:this.mapCenter);
        this.handleClose()
      }
    }
  }
</script>
<style lang="scss" scoped>
  @import "@/styles/variables";
  .common-dialog {
    /deep/.el-dialog__body{
      padding:20px 30px;
    }
    .el-input__inner{
      height:36px;
      line-height: 36px;
    }
  }
  .near-box{
    width:300px;
    height:500px;
  }
  .map-box{
    width:calc(100% - 320px);
    height:500px;
    margin:0;
    padding:0
  }
  #container{
    width:100%;
    height:100%;
  }
  /deep/ .el-input{
    min-width: auto;
  }
  .location-list{
    list-style: none;
    margin: 10px 0 0;
    padding:0;
    max-height: 460px;
    border:1px solid $color-border-light;
    overflow-y: auto;
  }
  .location-list li{
    list-style: none;
    padding:5px;
    border-bottom:1px solid $color-border-light;
    cursor: pointer;
    &:last-child{
      border-bottom: none;
    }
  }
  .location-list li.location-active{
    background-color: $color-primary;

    .location-title,.location-address{
      color:#fff;
    }
  }
  .location-title{
    font-size: 14px;
    color:$color-text-dark;
    font-weight: bold;
  }
  .location-address{
    font-size: 12px;
    color: $color-text-secondary;
    transform: scale(0.85);
  }
</style>

以逆地址解析为例写法为:

import request from "@/axios";
//逆地址解析
export const getAddressByLat = (params) =>{
  return request.jsonp('/ws/geocoder/v1', {
    output: "jsonp",
    ...params
  })
}

axios 调用 jsonp 方法

import axios from 'axios';
import {serialize} from '@/util/util';
import {Message} from 'element-ui';
axios.jsonp = function(url,data){
  if(!url) throw new Error('接口地址错误')
  function sortObjectByKeys(obj) {
    return Object.keys(obj)
      .sort()
      .reduce((sortedObj, key) => {
        sortedObj[key] = obj[key];
        return sortedObj;
      }, {});
  }
  const callback = 'CALLBACK' + Math.random().toString().substr(9,18)
  const time=Date.now();
  let newData=sortObjectByKeys({
    ...data,
    callback,
    time
  });
  
  let sign=md5(`${url}?${serialize(newData)}YOUR_SK`);
  const JSONP = document.createElement('script')
  JSONP.setAttribute('type','text/javascript')
  const headEle = document.getElementsByTagName('head')[0];
  JSONP.src = `https://apis.map.qq.com${url}?${serialize(newData)}&sig=${sign}`;
  return new Promise( (resolve) => {
    window[callback] = r => {
      if(r.status!='0'){
        Message({
          message: r.message,
          type: 'warning'
        });
      }
      resolve(r)
      headEle.removeChild(JSONP)
      delete window[callback]
    }
    headEle.appendChild(JSONP)
  })
}
export default axios;

YOUR_SK为腾讯地图签名验证时SK。 见下图:
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++11中重要的新特性之 lambda表达式 Part two

序言 在上一篇文章中&#xff0c;我们主要介绍了 C11 中的新增的关键词&#xff0c;以及 范围for循环 这类语法糖的使用和背后的逻辑。在这篇文章中我们会继续介绍一个特别重要的新特性分别是 lambda表达式 。 1. lambda表达式 1.1 lambda的定义 C11 中的 lambda表达式 是一种…

APB总线协议

一、APB总线介绍 关于总线的一些概念&#xff1a; 总线&#xff1a;计算机内部和计算机之间传输数据的共用通道。 总线位宽&#xff1a;总线能够一次性传送的二进制数据位数&#xff0c;例如8bit、16bit、32bit、64bit等。 总线工作频率&#xff1a;即时钟频率&#xff08;时…

PHP实现用户认证与权限管理的全面指南

目录 引言 1. 数据库设计 1.1 用户表&#xff08;users&#xff09; 1.2 角色表&#xff08;roles&#xff09; 1.3 权限表&#xff08;permissions&#xff09; 1.4 用户角色关联表&#xff08;user_roles&#xff09; 1.5 角色权限关联表&#xff08;role_permissions…

【内网渗透】内网渗透学习之域渗透常规方法

域渗透常规方法和思路 1、域内信息收集1.1、获取当前用户信息1.1.1、获取当前用户与域 SID1.1.2、查询指定用户的详细信息 1.2、判断是否存在域1.2、查询域内所有计算机1.3、查询域内所有用户组列表1.4、查询所有域成员计算机列表1.5、获取域密码信息1.6、获取域信任信息1.7、查…

最短路径算法:Dijkstra算法探险记

想象一下,你是一只小蚂蚁,名字叫小明。你住在一个大大的花园里,这个花园有很多小路,小路之间还有交叉点,就像是一个迷宫一样。现在,你接到了一个任务:找到从你家到花园里一个特定地方(比如一块超级大的糖果)的最短路径! 第一步:画出地图 首先,我们需要一张地图来…

YOLOv8改进 | 注意力机制 | 增强模型在图像分类和目标检测BAM注意力【小白必备 + 附完整代码】

秋招面试专栏推荐 &#xff1a;深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 &#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; 专栏目录 &#xff1a;《YOLOv8改进有效…

【模块化与包管理】:解锁【Python】编程的高效之道

目录 1.什么是模块&#xff1f; 2. 模块的导入过程 3. 理解命名空间 4. import语句的多种形式 5. 模块的执行与重新导入 6. 包&#xff08;Package&#xff09; 7. sys模块和os模块 sys模块 常用属性 示例&#xff1a;使用sys模块 os模块 常用功能 示例&#xff1…

前端埋点数据收集和数据上报

原文地址 什么是埋点 学名叫时间追踪(Event Tracking), 主要针对用户行为或者业务过程进行捕获&#xff0c;处理和发送相关技术及实施过程. 埋点是数据领域的一个专业术语&#xff0c;也是互联网领域的俗称&#xff0c;是互联网领域的俗称 埋点是产品数据分析的基础&#xf…

【AIGC】一、本地docker启动私有大模型

本地docker启动私有大模型 一、最终效果中英文对话生成代码 二、资源配置三、搭建步骤启动docker容器登录页面首次登录请注册登录后的效果 配置模型尝试使用选择模型选项下载模型选择适合的模型开始下载 试用效果返回首页选择模型中英文对话生成代码 四、附录资源监控 五、参考…

动手学深度学习54 循环神经网络

动手学深度学习54 循环神经网络 1. 循环神经网络RNN2. QA 1. 循环神经网络RNN h t h_t ht​ 与 h t − 1 h_{t-1} ht−1​ x t − 1 x_{t-1} xt−1​有关 x t x_t xt​ 与 h t h_t ht​ x t − 1 x_{t-1} xt−1​ 有关 怎么把潜变量变成RNN–假设更简单 潜变量和隐变量的区…

Java面试八股之什么是布隆过滤器

什么是布隆过滤器 布隆过滤器&#xff08;Bloom Filter&#xff09;是一种空间效率极高的概率型数据结构&#xff0c;用于判断一个元素是否可能存在于一个集合中。布隆过滤器可以给出“可能存在”或“一定不存在”的答案&#xff0c;但不能保证“一定存在”。其主要特点是&…

WTM的项目中EFCore如何适配人大金仓数据库

一、WTM是什么 WalkingTec.Mvvm框架&#xff08;简称WTM&#xff09;最早开发与2013年&#xff0c;基于Asp.net MVC3 和 最早的Entity Framework, 当初主要是为了解决公司内部开发效率低&#xff0c;代码风格不统一的问题。2017年9月&#xff0c;将代码移植到了.Net Core上&…

开源项目有哪些机遇与挑战

目录 1.概述 2.开源项目的发展趋势 2.1. 开源项目的发展现状 2.2. 开源社区的活跃度 2.3. 开源项目在技术创新中的作用 3.参与开源的经验分享 3.1. 选择开源项目 3.2. 理解项目结构和文档 3.3. 贡献代码 3.4. 与开源社区的合作 3.5. 学习和成长 4.开源项目的挑战 …

buuctf 二维码

文件下载下来是一个png的文件 做misc永远的好习惯就是先运行,后010 先运行,这个运行肯定就是扫码 啥也没有 里面还有个ZIP文件(zip的发明人名字是PK) 放在kali上binwalk分离 CTF工具隐写分离神器Binwalk安装和详细使用方法_binwalk下载-CSDN博客 里面有个text,需要密码 我…

ESP32驱动摄像头:1.驱动OV2640模块(待验证)

一、装ArduCam库和ESPAsyncWebServer库 二、参考代码 #include <Wire.h> #include <ArduCAM.h> #include <SPI.h> #include <WiFi.h> #include <ESPAsyncWebServer.h>#define CAM_CS 32 // modify according to your own wiring #define OV2640…

IP 地址:优化网络游戏

IP地址和网络游戏 在现代网络游戏中&#xff0c;IP地址不仅用于服务器分配&#xff0c;还能针对性进行玩家匹配与优化网络延迟。本文将探讨IP地址在网络游戏中的具体应用。 *服务器分配* 全球服务器分布&#xff1a; 网络游戏需要在全球范围内提供快速、稳定的连接&#xff…

【机器学习】主成分分析(PCA):数据降维的艺术

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 主成分分析&#xff08;PCA&#xff09;&#xff1a;数据降维的艺术引言PCA的基…

【TypeScript 学习】TypeScript 枚举类型发散:基于位运算的权限管理 CRUD 操作

文章目录 TypeScript 枚举类型发散&#xff1a;基于位运算的权限管理 CRUD 操作1 问题由来2 具体实现2.1 新增权限2.2 删除权限2.3 查询权限&#xff08;即判定存在与否&#xff09;2.4 修改权限2.5 完整测试 3 小结 TypeScript 枚举类型发散&#xff1a;基于位运算的权限管理 …

鸿蒙开发:Universal Keystore Kit(密钥管理服务)【加解密(C/C++)】

加解密(C/C) 以AES 256密钥为例&#xff0c;完成加解密。具体的场景介绍及支持的算法规格。 在CMake脚本中链接相关动态库 target_link_libraries(entry PUBLIC libhuks_ndk.z.so)开发步骤 生成密钥 指定密钥别名。初始化密钥属性集。调用OH_Huks_GenerateKeyItem生成密钥)…

[Linux安全运维] Linux用户以及权限管理

Linux用户以及权限管理 Linux用户和组 用户信息文件pasawd /etc/passwd文件用于存储用户的信息 :用于分割不同的字段信息 字段示例&#xff08;第一行&#xff09;含义说明1root用户名2x密码占位符x代表用户有密码存储在shadow文件中无内容代表用户登录系统不需要密码30UID…