vue | 在 Vue 3 项目中集成高德地图(AMap)

一、准备工作

1. 获取高德地图 Key

  • 登录 高德开放平台
  • 创建应用 → 获取 Web 端 JS API Key

二、安装依赖

bash 复制代码
npm install @amap/amap-jsapi-loader
# 或
yarn add @amap/amap-jsapi-loader

不要直接通过 <script> 引入 CDN,避免与 Vue 响应式冲突。


三、封装高德地图 Hook

创建 hooks/useAmap.js

javascript 复制代码
import { onMounted, onUnmounted, ref } from 'vue'
import AMapLoader from '@amap/amap-jsapi-loader'

const useAmap = (containerId, options = {}) => {
  const map = ref(null)
  const AMap = ref(null)

  const initMap = async () => {
    try {
      // 加载高德地图 SDK
      const amap = await AMapLoader.load({
        key: '', // 替换为你的 key
        version: '2.0', // 推荐 2.0+
        plugins: [
          'AMap.Geolocation',
          'AMap.Marker',
          'AMap.InfoWindow',
          'AMap.Polyline',
          'AMap.Circle',
          'AMap.Scale',
          'AMap.ToolBar',
        ],
      })

      AMap.value = amap

      // 初始化地图
      const mapInstance = new amap.Map(containerId, {
        zoom: options.zoom || 16,
        center: options.center || [116.397428, 39.90923], // 默认北京
        viewMode: '3D',
        layers: [new amap.TileLayer.Satellite(), new amap.TileLayer.RoadNet()],
        visible: true,
        resizeEnable: true,
        zooms: [2, 20],
      })

      map.value = mapInstance

      // 可选:添加缩放控件等
      mapInstance.addControl(new amap.ToolBar())
      mapInstance.addControl(new amap.Scale())

      return mapInstance
    } catch (error) {
      console.error('高德地图加载失败:', error)
    }
  }

  onMounted(() => {
    initMap()
  })

  onUnmounted(() => {
    if (map.value) {
      map.value.destroy()
    }
  })

  return {
    map,
    AMap,
    initMap,
  }
}

export default useAmap

四、在组件中使用

javascript 复制代码
<template>
  <div id="amap-container" class="map-container"></div>
</template>

<script setup>
import { onMounted } from 'vue'
import useAmap from '@/hooks/useAmap'

const { map, AMap, initMap } = useAmap('amap-container', {
  zoom: 13,
  center: [84.920629, 45.417129],
})
onMounted(() => {
  initMap()
})
</script>

<style scoped>
.map-container {
  width: 100%;
  height: 600px;
  border-radius: 8px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
</style>

五、实现效果

相关推荐
JIngJaneIL16 分钟前
基于springboot + vue古城景区管理系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot·后端
敲敲了个代码23 分钟前
隐式类型转换:哈基米 == 猫 ? true :false
开发语言·前端·javascript·学习·面试·web
澄江静如练_33 分钟前
列表渲染(v-for)
前端·javascript·vue.js
JustHappy1 小时前
「chrome extensions🛠️」我写了一个超级简单的浏览器插件Vue开发模板
前端·javascript·github
Loo国昌1 小时前
Vue 3 前端工程化:架构、核心原理与生产实践
前端·vue.js·架构
sg_knight1 小时前
拥抱未来:ECMAScript Modules (ESM) 深度解析
开发语言·前端·javascript·vue·ecmascript·web·esm
LYFlied1 小时前
【每日算法】LeetCode 17. 电话号码的字母组合
前端·算法·leetcode·面试·职场和发展
开发者小天1 小时前
react中useEffect的用法,以及订阅模式的原理
前端·react.js·前端框架
前端白袍1 小时前
Vue:如何实现一个具有复制功能的文字按钮?
前端·javascript·vue.js