文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

vue3中如何使用高德地图api

2023-07-05 10:39

关注

本篇内容介绍了“vue3中如何使用高德地图api”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

前置工作

在开发之前我们需要了解 vue3 中接入高德地图的几个步骤

npm i @amap/amap-jsapi-loader --save
import AMapLoader from '@amap/amap-jsapi-loader'

vue3中如何使用高德地图apivue2vue3 是有区别的,这里我们使用的是 vue3 ,但这里 vue3 的方式还是选项式,不是组合式的,我自己写的时候使用的是组合式的,且集成了 ts, 我后面发布完整 .vue 文件的时候 会去掉标签上的 ts,因为类型还没有完善,等后面完善了再贴更改以后得。为什么要使用 shallowRef 官方也给出了说明原因。

示例模块

这里我直接把我前面,写过的 地图业务需求的业务逻辑拿过来的,没有使用框架,直接在一个 html 文件当中引入,链接大家可以点击下面进行查看:
高德地图jsApi的使用
高德地图jsApi的点和线配置
高德地图jsApi的右键设置
高德地图jsApi的点位新增
高德地图jsApi的图例
使用vue3 的时候,实例化的方式, this 的问题, 以及插入字符串模板的时候 事件响应的方式都需要更改,还是很麻烦的

模块的引入

import AMapLoader from '@amap/amap-jsapi-loader'const initMap = () => {  AMapLoader.load({    key: 'b59c490f61a694b9d7576dd864f74d6e', // 申请好的Web端开发者Key,首次调用 load 时必填    version: '2.0', // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15    plugins: ['AMap.Scale', 'AMap.ToolBar', 'AMap.MouseTool'], // 需要使用的的插件列表,如比例尺'AMap.Scale'等    Loca:{      version:'2.0.0'    }  })    .then((res) => {            AMap.value = res      // 上来就显示的中心点  北京 116.397, 39.918      var lnglat = new res.LngLat(105, 38)      map.value = new res.Map('container', {        //设置地图容器id        viewMode: '3D', //是否为3D地图模式        zoom: 5, //初始化地图级别        center: lnglat, //初始化地图中心点位置      })      map.value.clearMap() // 清除地图覆盖物      // 地图是否可拖拽和缩放      map.value.setStatus({        dragEnable: true, // 是否可拖拽        zoomEnable: true, // 是否可缩放      })      initWindow()      // 添加一些分布不均的点到地图上,地图上添加三个点标记,作为参照      coordData.forEach(function (marker) {        setMarker(marker)      })      let renderLine = setLine(coordData)      // 设置线      let polyline = renderLine.reduce((prev, item, index) => {        let weight = item.type === 1 ? 5 : 3        let color = item.type === 1 ? headColors[0] : headColors[1]        prev.push(setLines(item.current, color, weight))        return prev      }, [])      map.value.add([...polyline]) // 绘制线      //创建右键菜单      menuInstance.value = new ContextMenu(map.value)      let loca = new Loca.Container({          map:map.value,      });      window._loca = loca;      // 图例, 图例可以实例化多个,使用定位来设置位置      let lengend = new Loca.Legend({          loca: loca,          title: {              label: '管道类型',              fontColor: 'rgba(255,255,255,1)',              fontSize: '16px'          },          style: {              backgroundColor: 'rgba(255,255,255,0.2)',              left: '20px',              bottom: '40px',              fontSize: '12px'          },          dataMap: [              { label: '省级管道', color: headColors[1] },              { label: '县级管道', color: headColors[0] },          ],      });      //修改图例排列方式      document.getElementsByClassName("amap-loca loca-controls")[0].setAttribute('id', 'testid')        var lis = document.querySelectorAll("#testid li");        for (var i = 0; i < lis.length; i++) {          console.log(lis[i]);          lis[i].setAttribute("class", 'test'          );      }    })    .catch((e) => {      console.log('error', e)    })}onMounted(() => {  initMap()})

右键菜单

右键菜单, 右键菜单这里官方给我们的示例是使用一个 函数 进行实例化,里面使用了 this, 所以这个我单独拿出来,首先我们看一下官方的 demo

vue3中如何使用高德地图api

vue3中如何使用高德地图api

vue3中如何使用高德地图api
一种是在指定点位上打开,另一种是在非点位的空白处打开,指定点位处打开的其实叫信息窗体,只不过是通过右键的方式触发,那个没有上面这个右键菜单麻烦。

const { ctx } = getCurrentInstance()const _this = ctx//自定义菜单类class ContextMenu {  constructor(map) {    var me = _this    //地图中添加鼠标工具MouseTool插件    _this.mouseTool = new AMap.value.MouseTool(map)    _this.contextMenuPositon = null    const fragment = document.createElement('div') // 使用 DOM 方式, 方便添加事件    fragment.className = 'info context_menu'    const p = document.createElement('p')    p.addEventListener('click', this.delMarkerMenu)    p.textContent = '移除上次选中信息'    fragment.appendChild(p)    //通过content自定义右键菜单内容    _this.contextMenu = new AMap.value.ContextMenu({      isCustom: true,      content: fragment,    })    //地图绑定鼠标右击事件——弹出右键菜单    map.on('rightclick', function (e) {      me.contextMenu.open(map, e.lnglat)      me.contextMenuPositon = e.lnglat //右键菜单位置    })  }  delMarkerMenu() {    // 右键菜单上次选中点的信息    clearPoint()    _this.mouseTool.close()    _this.contextMenu.close()  }}

完整代码

<!-- * @Description: 地图 * @Autor: codeBo * @Date: 2023-03-06 16:10:10 * @LastEditors: gjzxlihaibo@163.com * @LastEditTime: 2023-03-07 14:59:08--><template>  <div id="root">    <div>      <h4>添加选点请输入坐标</h4>      <label>        经度:        <input />      </label>      <label>        纬度:        <input />      </label>      <button>输入完成</button>      <button>清空输入</button>    </div>    <div id="container"></div>  </div></template><script setup>import { onMounted, reactive, ref, getCurrentInstance } from 'vue'import AMapLoader from '@amap/amap-jsapi-loader'import { shallowRef } from 'vue'import { coordData } from './data'const map = shallowRef(null)const { ctx } = getCurrentInstance()const _this = ctxconst menuInstance = ref() // menu 实例let AMap = ref() // map 实例let currentPonit = ref<HTMLElement | null>(null) // 存储当前选中点 DOMlet currentData = reactive({}) // 当前选重点信息let sourceInfoWindow = ref()const headColors = ['#3366bb', '#6622FF']// 工具方法// 修改DOM 类名function changeStyle(res, data) {  if (currentPonit.value !== null) {    currentPonit.value.classList.remove('active')  }  currentPonit.value = res.children[0]  currentData = data  currentPonit.value.classList.add('active')}// 清除点信息function clearPoint() {  if (currentPonit.value) {    currentPonit.value.classList.remove('active')  }  currentPonit.value = null  currentData = {}}// 设置线信息function setLines(lnglat, color, weight) {  return new AMap.value.Polyline({    path: lnglat,    // showDir:true ,// 设置线方向    strokeColor: color, // 线颜色    strokeWeight: weight, // 线宽    strokeOpacity: 0.6, // 透明度  })}function markerClick(e) {  console.log('sourceInfoWindow.value', sourceInfoWindow.value, e.target)  sourceInfoWindow.value.setContent(e.target.contents)  sourceInfoWindow.value.open(map.value, e.target.getPosition())}function setInput(e, name) {  let text =    e.target.parentElement.parentElement.children[0].innerText.split(      '供给点',    )[0]  let current = coordData.filter((item) => {    return item.name === text  })  window.localStorage.setItem(text + name, e.target.value)}const initWindow = () => {  // 信息窗体  let infoWindow = new AMap.value.InfoWindow({    offset: new AMap.value.Pixel(0, -10),    retainWhenClose: true,  })  sourceInfoWindow.value = infoWindow  infoWindow.on('open', function (...arg) {    let inputOut = document.getElementById('inputOut')    let inputPro = document.getElementById('inputPro')    inputOut.addEventListener('change', (e) => {      setInput(e, 'inputOut')      window.location.reload()    })    inputPro.addEventListener('change', (e) => {      setInput(e, 'inputPro')      window.location.reload()    })  })}// 抽离点位信息设置function setMarker(marker) {  //创建右键菜单  var contextMenu = new AMap.value.ContextMenu()  //右键放大  contextMenu.addItem(    '放大一级',    function () {      map.value.zoomIn()    },    0,  )  //右键缩小  contextMenu.addItem(    '缩小一级',    function () {      map.value.zoomOut()    },    1,  )  contextMenu.addItem('设置起点', function () {    console.log('设置起点', marker, markerd.dom)    changeStyle(markerd.dom, marker)    contextMenu.close() // 关闭右键菜单  })  contextMenu.addItem('与起点连线', function () {    if (!currentPonit) {      alert('请选择起点')      contextMenu.close()      return    } else {      // 这里其实可以根据数据判定线类型了,因为第二个选中点的信息+和第一个选中点的信息都有了,但是过滤方法会比较复杂      let path = [currentData.position, marker.position]      const polyline1 = setLines(path, '#3366bb', 5)      map.value.add([polyline1])      clearPoint()    }    contextMenu.close() // 关闭右键菜单  })  let content = '<div></div>'  var markerd = new AMap.value.Marker({    map: map.value,    // icon: marker?.icon,    content,    offset: new AMap.value.Pixel(-8, -8),    visible: true, // 点标记是否可见    position: [marker.position[0], marker.position[1]],  })  let inputO = window.localStorage.getItem(marker.name + 'inputOut')  let inputP = window.localStorage.getItem(marker.name + 'inputPro')  // 左键点击的信息窗体, 宽度会在碰触到容器边缘的时候自适应的缩小  markerd.contents = `    <div>${marker.name}供给点</div>    <div>出口压力:<input id="inputOut" value="${      inputO ?? marker?.pointData?.out    }"/>kPa</div>    <div>供给量:<input id="inputPro" value="${      inputP ?? marker?.pointData?.provide    }" />m³</div>    <div>位置:经度${marker.position[0]},纬度${marker.position[1]}</div>`  markerd.data = marker  markerd.on('click', markerClick)  if (marker.name === '新疆') {    // 触发上面的点击事件    markerd.emit('click', { target: markerd })  }  //绑定鼠标右击事件——弹出右键菜单  markerd.on('rightclick', function (e) {    contextMenu.open(map.value, e.lnglat)  })  return markerd}//自定义菜单类class ContextMenu {  constructor(map) {    var me = _this    //地图中添加鼠标工具MouseTool插件    _this.mouseTool = new AMap.value.MouseTool(map)    _this.contextMenuPositon = null    const fragment = document.createElement('div') // 使用 DOM 方式, 方便添加事件    fragment.className = 'info context_menu'    const p = document.createElement('p')    p.addEventListener('click', this.delMarkerMenu)    p.textContent = '移除上次选中信息'    fragment.appendChild(p)    //通过content自定义右键菜单内容    _this.contextMenu = new AMap.value.ContextMenu({      isCustom: true,      content: fragment,    })    //地图绑定鼠标右击事件——弹出右键菜单    map.on('rightclick', function (e) {      me.contextMenu.open(map, e.lnglat)      me.contextMenuPositon = e.lnglat //右键菜单位置    })  }  delMarkerMenu() {    // 右键菜单上次选中点的信息    clearPoint()    _this.mouseTool.close()    _this.contextMenu.close()  }}// 过滤线方法function setLine(arr) {  return arr.reduce((prev, item) => {    if (item?.line) {      prev.push(...item.line)    }    return prev  }, [])}const initMap = () => {  AMapLoader.load({    key: 'b59c490f61a694b9d7576dd864f74d6e', // 申请好的Web端开发者Key,首次调用 load 时必填    version: '2.0', // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15    plugins: ['AMap.Scale', 'AMap.ToolBar', 'AMap.MouseTool'], // 需要使用的的插件列表,如比例尺'AMap.Scale'等    Loca:{      version:'2.0.0'    }  })    .then((res) => {            AMap.value = res      // 上来就显示的中心点  北京 116.397, 39.918      var lnglat = new res.LngLat(105, 38)      map.value = new res.Map('container', {        //设置地图容器id        viewMode: '3D', //是否为3D地图模式        zoom: 5, //初始化地图级别        center: lnglat, //初始化地图中心点位置      })      map.value.clearMap() // 清除地图覆盖物      // 地图是否可拖拽和缩放      map.value.setStatus({        dragEnable: true, // 是否可拖拽        zoomEnable: true, // 是否可缩放      })      initWindow()      // 添加一些分布不均的点到地图上,地图上添加三个点标记,作为参照      coordData.forEach(function (marker) {        setMarker(marker)      })      let renderLine = setLine(coordData)      // 设置线      let polyline = renderLine.reduce((prev, item, index) => {        let weight = item.type === 1 ? 5 : 3        let color = item.type === 1 ? headColors[0] : headColors[1]        prev.push(setLines(item.current, color, weight))        return prev      }, [])      map.value.add([...polyline]) // 绘制线      //创建右键菜单      menuInstance.value = new ContextMenu(map.value)      let loca = new Loca.Container({          map:map.value,      });      window._loca = loca;      // 图例, 图例可以实例化多个,使用定位来设置位置      let lengend = new Loca.Legend({          loca: loca,          title: {              label: '管道类型',              fontColor: 'rgba(255,255,255,1)',              fontSize: '16px'          },          style: {              backgroundColor: 'rgba(255,255,255,0.2)',              left: '20px',              bottom: '40px',              fontSize: '12px'          },          dataMap: [              { label: '省级管道', color: headColors[1] },              { label: '县级管道', color: headColors[0] },          ],      });      //修改图例排列方式      document.getElementsByClassName("amap-loca loca-controls")[0].setAttribute('id', 'testid')        var lis = document.querySelectorAll("#testid li");        for (var i = 0; i < lis.length; i++) {          console.log(lis[i]);          lis[i].setAttribute("class", 'test'          );      }    })    .catch((e) => {      console.log('error', e)    })}onMounted(() => {  initMap()})</script><style>#container {  width: 1350px;  height: 900px;}#root {  display: flex;  width: 100%;}#root > div:first-child {  width: 200px;  margin-right: 10px;  padding: 5px;  box-shadow: 2px 2px 2px 2px #333;}#root > div:first-child {  display: flex;  flex-direction: column;}.context_menu {  position: relative;  min-width: 12rem;  padding: 0;  background-color: white;}.context_menu p {  cursor: pointer;  padding: 0.25rem 1.25rem;}.context_menu p:hover {  background: #ccc;}.btn {  width: 80px;  margin-top: 10px;}.marker-route {  width: 15px;  height: 15px;  background-color: #22ddb8;  border-radius: 10px;}.active {  background-color: #f76809;}.content {  background-color: rgba(0, 0, 0, 0.3);  padding: 1px;  color: white;  display: flex;  align-items: center;}.content span {  display: block;  width: 20px;  height: 20px;  background-color: #3366bb;  margin: 0 10px;}.content p {  margin-right: 10px;}.test {  height: 30px;  box-sizing: content-box;  padding: 2px 10px;  line-height: 30px;  display: inline;  float: left;}.test a {  color: #333 !important;}.test span {  width: 80px !important;  margin-left: 10px;  border-radius: 10px;}.amap-info-content {  background-color: rgba(255, 255, 255, 0.6);}.test_container {  background-color: rgba(255, 255, 255, 0.6);  display: flex;  width: 180px;  flex-direction: column;  padding: 10px 18px 10px 10px;  line-height: 1.4;  overflow: auto;  justify-content: center;  align-items: center;  border: 1px solid rgba(0, 0, 0, 0.2);}.input_inner {  margin-right: 5px;  border: 1px solid #333;  border-radius: 2px;  width: 30px;}</style>

export const coordData = [  {    name: '黑龙江',    position: [127, 47],    pointData: {      out: 100,      provide: 10,    },    line: [      {        current: [          [127, 47],          [126, 43],        ],        type: 1,      },    ],  },  {    name: '吉林',    position: [126, 43],    pointData: {      out: 120,      provide: 11,    },    line: [      {        current: [          [126, 43],          [113, 41],        ],        type: 1,      },    ],  }, ]

“vue3中如何使用高德地图api”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯