当前位置: 首页 > news >正文

vue3项目中接入高德地图组件。

文章目录

  • 一、高德地图应用注册。
  • 二、注册步骤
  • 三、接入Vue3项目
    • 1.安装依赖
    • 2.配置 securityJsCode
    • 3.增加对应类型
    • 4.初始化高德地图资源
    • 5.初始化地图
  • 四、高德地图-物流轨迹配置
  • 五、高德地图-绘制标记
  • 六、完整代码参考
  • 总结


一、高德地图应用注册。

高德地图开放平台: https://lbs.amap.com/api/jsapi-v2/guide/abc/prepare
Vue中使用: https://lbs.amap.com/api/jsapi-v2/guide/webcli/map-vue1

注册&认证完毕===>创建web应用====>得到 key 和 jscode

二、注册步骤

在这里插入图片描述

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

三、接入Vue3项目

1.安装依赖

pnpm add @amap/amap-jsapi-loader

2.配置 securityJsCode

window._AMapSecurityConfig = {
  securityJsCode: '自己的秘钥'
}

3.增加对应类型

interface Window {
  _AMapSecurityConfig: {
    securityJsCode: string
  }
}  

4.初始化高德地图资源

import AMapLoader from '@amap/amap-jsapi-loader'

cnst initMap = () => {
	MapLoader.load({
    key: '自己的key',
    version: '2.0'
  }).then((AMap) => {
    // 使用 Amap 初始化地图
  })
}
onMounted(async () => {
	initMap()
})

5.初始化地图

const map = new AMap.Map('map', {
  mapStyle: 'amap://styles/whitesmoke',
  zoom: 12
})

四、高德地图-物流轨迹配置

步骤:

  • 绘制轨迹
  • 关闭默认覆盖物
  • 绘制位置

样例代码:

AMap.plugin('AMap.Driving', function () {
  const driving = new AMap.Driving({
    map: map,
    showTraffic: false,
    hideMarkers: true
  })

  if (
    logistics.value?.logisticsInfo &&
    logistics.value.logisticsInfo.length >= 2
  ) {
    const list = [...logistics.value.logisticsInfo]
    // 起点
    const start = list.shift()
    // 终点
    const end = list.pop()
    driving.search(
      [start?.longitude, start?.latitude],
      [end?.longitude, end?.latitude],
      { waypoints: list.map((item) => [item.longitude, item.latitude]) },
      () => {
        // 规划完毕
      }
    )
  }
})

五、高德地图-绘制标记

参考文档
在这里插入图片描述

样例代码:

if (
        logistics.value?.logisticsInfo &&
        logistics.value.logisticsInfo.length >= 2
      ) {
        const list = [...logistics.value.logisticsInfo]
        // 创建标记函数
        const getMarker = (
          point: Location,
          image: string,
          width = 25,
          height = 30
        ) => {
          const icon = new AMap.Icon({
            size: new AMap.Size(width, height),
            image,
            imageSize: new AMap.Size(width, height)
          })
          const marker = new AMap.Marker({
            position: [point?.longitude, point?.latitude],
            icon: icon,
            offset: new AMap.Pixel(-width / 2, -height)
          })
          return marker
        }
        // 起点
        const start = list.shift()
        const startMarker = getMarker(start!, startImg)
        map.add(startMarker)
        // 终点
        const end = list.pop()
        const endMarker = getMarker(end!, endImg)
        map.add(endMarker)

        driving.search(
          [start?.longitude, start?.latitude],
          [end?.longitude, end?.latitude],
          { waypoints: list.map((item) => [item.longitude, item.latitude]) },
          () => {
            // 规划完毕
            // 运输位置
            const curr = logistics.value?.currentLocationInfo
            const currMarker = getMarker(curr!, carImg, 33, 20)
            map.add(currMarker)
            // 3s后定位当中间进行缩放
            setTimeout(() => {
              map.setFitView([currMarker])
              map.setZoom(10)
            }, 3000)
          }
        )
      }

六、完整代码参考

<script setup lang="ts">
import { getMedicalOrderLogistics } from '@/services/order'
import type { Logistics, Location } from '@/types/order'
import { onMounted, ref } from 'vue'
import { useRoute } from 'vue-router'
import AMapLoader from '@amap/amap-jsapi-loader'
import startImg from '@/assets/start.png'
import endImg from '@/assets/end.png'
import carImg from '@/assets/car.png'

// 获取物流信息
const route = useRoute()
const logistics = ref<Logistics>()
onMounted(async () => {
  const res = await getMedicalOrderLogistics(route.params.id as string)
  logistics.value = res.data
  initMap()
})

// 配置地图
window._AMapSecurityConfig = {
  securityJsCode: '自己的秘钥'
}
// 初始化地图
const initMap = () => {
  AMapLoader.load({
    key: '自己的key',
    version: '2.0'
  }).then((AMap) => {
    // 使用 Amap 初始化地图
    const map = new AMap.Map('map', {
      mapStyle: 'amap://styles/whitesmoke',
      zoom: 12
    })
    AMap.plugin('AMap.Driving', function () {
      const driving = new AMap.Driving({
        map: map,
        showTraffic: false,
        hideMarkers: true
      })
      if (
        logistics.value?.logisticsInfo &&
        logistics.value.logisticsInfo.length >= 2
      ) {
        const list = [...logistics.value.logisticsInfo]
        // 创建标记函数
        const getMarker = (
          point: Location,
          image: string,
          width = 25,
          height = 30
        ) => {
          const icon = new AMap.Icon({
            size: new AMap.Size(width, height),
            image,
            imageSize: new AMap.Size(width, height)
          })
          const marker = new AMap.Marker({
            position: [point?.longitude, point?.latitude],
            icon: icon,
            offset: new AMap.Pixel(-width / 2, -height)
          })
          return marker
        }

        // 存储所有标记点
        const allMarkers = [] as any[] // 使用类型断言

        // 起点
        const start = list.shift()
        const startMarker = getMarker(start!, startImg)
        map.add(startMarker)
        allMarkers.push(startMarker)

        // 终点
        const end = list.pop()
        const endMarker = getMarker(end!, endImg)
        map.add(endMarker)
        allMarkers.push(endMarker)

        // 运输位置
        const curr = logistics.value?.currentLocationInfo
        const currMarker = getMarker(curr!, carImg, 33, 20)
        map.add(currMarker)
        allMarkers.push(currMarker)

        // 先设置一个合适的初始视野
        map.setFitView(allMarkers)

        // 然后进行路线规划
        driving.search(
          [start?.longitude, start?.latitude],
          [end?.longitude, end?.latitude],
          { waypoints: list.map((item) => [item.longitude, item.latitude]) },
          () => {
            // 路线规划完成后再次调整视野,确保路线也在视野内
            map.setFitView(allMarkers)

            // 3秒后再聚焦到运输车辆位置
            setTimeout(() => {
              map.setFitView([currMarker])
              map.setZoom(10)
            }, 3000)
          }
        )
      }
    })
  })
}
</script>

<template>
  <div class="order-logistics-page">
    <div id="map">
      <div class="title">
        <van-icon name="arrow-left" @click="$router.back()" />
        <span>{{ logistics?.statusValue }}</span>
        <van-icon name="service" />
      </div>
      <div class="current">
        <p class="status">
          {{ logistics?.statusValue }} 预计{{ logistics?.estimatedTime }}送达
        </p>
        <p class="predict">
          <span>{{ logistics?.name }}</span>
          <span>{{ logistics?.awbNo }}</span>
        </p>
      </div>
    </div>
    <div class="logistics">
      <p class="title">物流详情</p>
      <van-steps direction="vertical" :active="0">
        <van-step v-for="item in logistics?.list" :key="item.id">
          <p class="status">{{ item.statusValue }}</p>
          <p class="content">{{ item.content }}</p>
          <p class="time">{{ item.createTime }}</p>
        </van-step>
      </van-steps>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.order-logistics-page {
  --van-step-icon-size: 18px;
  --van-step-circle-size: 10px;
}
#map {
  height: 450px;
  background-color: var(--cp-bg);
  overflow: hidden;
  position: relative;
  .title {
    background-color: #fff;
    height: 46px;
    width: 355px;
    border-radius: 4px;
    display: flex;
    align-items: center;
    padding: 0 15px;
    font-size: 16px;
    position: absolute;
    left: 10px;
    top: 10px;
    box-sizing: border-box;
    box-shadow: 0px 0px 22px 0px rgba(229, 229, 229, 0.5);
    z-index: 999;
    > span {
      flex: 1;
      text-align: center;
    }
    .van-icon {
      font-size: 18px;
      color: #666;
      &:last-child {
        color: var(--cp-primary);
      }
    }
  }
  .current {
    height: 80px;
    border-radius: 4px;
    background-color: #fff;
    height: 80px;
    width: 355px;
    box-sizing: border-box;
    padding: 15px;
    position: absolute;
    left: 10px;
    bottom: 10px;
    box-shadow: 0px 0px 22px 0px rgba(229, 229, 229, 0.5);
    z-index: 999;
    .status {
      font-size: 15px;
      line-height: 26px;
    }
    .predict {
      color: var(--cp-tip);
      font-size: 13px;
      margin-top: 5px;
      > span {
        padding-right: 10px;
      }
    }
  }
}
.logistics {
  padding: 0 10px 20px;
  .title {
    font-size: 16px;
    padding: 15px 5px 5px;
  }
  .van-steps {
    :deep(.van-step) {
      &::after {
        display: none;
      }
    }
    .status {
      font-size: 15px;
      color: var(--cp-text3);
      margin-bottom: 4px;
    }
    .content {
      font-size: 13px;
      color: var(--cp-tip);
      margin-bottom: 4px;
    }
    .time {
      font-size: 13px;
      color: var(--cp-tag);
    }
  }
}
</style>

最终效果:
在这里插入图片描述

总结

这样,你就可以在 Vue 项目中集成高德地图,并进行基本的地图显示和交互了。

相关文章:

  • SV学习笔记——数组、队列
  • ​​《从事件冒泡到处理:前端事件系统的“隐形逻辑”》
  • 【Java代码审计 | 第十三篇】XXE漏洞成因及防范
  • 数据结构第六节:AVL树(初阶)
  • API调试工具的无解困境:白名单、动态IP与平台设计问题
  • STM32基础教程——对射式红外传感器计数实验
  • java读取Markdown配置文件
  • 【2025前端高频面试题——系列二之vue生命周期:vue2/vue3】
  • 【量化交易笔记】15.因子的来源和生成
  • FX-C++结构体与类的区别
  • 英语-新概念-第三册
  • 基于PyTorch的深度学习3——非标量反向传播
  • 轻量级TCC框架的实现
  • c++中的数学函数库(少)
  • 基于策略模式的智能提示语生成器设计与实现——以Tkinter GUI开发为例
  • 软考 中级软件设计师 考点知识点笔记总结 day02
  • AI赋能零代码编程基石:Anaconda全栈环境搭建与避坑指南
  • Golang | Gin(简洁版)
  • 深入Flink运行时架构:JobManager与TaskManager协作全解析
  • numpy常用函数详解
  • 集团网站设计欣赏/北京优化推广
  • 手机微网站建设案例及报告/郑州网络推广专业公司
  • 数据分析师就业前景如何/搜索引擎优化工具有哪些
  • 吉安市网站建设/百度竞价广告怎么收费
  • 怎么把网站制作成app/郑州网络推广方案
  • 长春公司网站建设/世界足球排名前100