You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Leaflet地图报错:ReferenceError: L is not defined 求助

问题排查:Leaflet地图仅首次加载有效且报错L is not defined

问题现象

  • 首次保存代码后地图可正常显示,后续路由切换或组件重新挂载时地图失效

  • 控制台抛出两类错误:

    runtime-core.esm-bundler.js:38 [Vue warn]: Unhandled error during execution of mounted hook
    at
    ...(省略后续组件栈)

    Uncaught (in promise) ReferenceError: L is not defined
    at LeafletMap.vue:24:1
    ...(省略调用栈)

核心原因

  1. Leaflet全局对象未正确引入:仅通过style中的CDN导入样式,未在JS中引入Leaflet核心库,首次加载依赖浏览器缓存偶然可用,后续加载时L全局变量丢失
  2. 异步语法误用:Leaflet的API均为同步方法,await关键字导致代码逻辑异常,触发未处理的Promise错误

解决方案

1. 安装并正确引入Leaflet依赖

先通过包管理器安装Leaflet:

npm install leaflet

在组件中替换CDN导入,改为本地导入:

<script setup>
import L from 'leaflet'
import 'leaflet/dist/leaflet.css'
// ... 其余代码
</script>

<template>
  <div class="relative h-96 w-full" ref="mapContainer"></div>
</template>

<style scoped>
/* 移除原有的@import CDN样式 */
</style>

2. 修正mounted钩子中的异步错误

移除所有不必要的await关键字,Leaflet方法均为同步执行:

onMounted(() => {
  map.value = L.map(mapContainer.value, mapOptions)
  L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
    attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
  }).addTo(map.value)
  marker.value = L.marker([props.lat, props.lng]).addTo(map.value)
})

3. 优化监听与销毁逻辑

合并经纬度监听,增加空值判断避免报错:

// 合并lat和lng的监听
watch([() => props.lat, () => props.lng], () => {
  if (marker.value && map.value) {
    marker.value.setLatLng([props.lat, props.lng])
    map.value.setView([props.lat, props.lng], 13)
  }
})

// 组件销毁时增加空值判断
onUnmounted(() => {
  if (map.value) {
    map.value.remove()
    map.value = null
    marker.value = null
  }
})

完整修正后的组件代码

<script setup>
import L from 'leaflet'
import 'leaflet/dist/leaflet.css'

const props = defineProps({
  lat: {
    type: Number,
    required: true
  },
  lng: {
    type: Number,
    required: true
  }
})

const map = ref(null)
const marker = ref(null)
const mapContainer = ref(null)
const mapOptions = {
  center: [props.lat, props.lng],
  zoom: 13,
  zoomControl: false
}

onMounted(() => {
  map.value = L.map(mapContainer.value, mapOptions)
  L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
    attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
  }).addTo(map.value)
  marker.value = L.marker([props.lat, props.lng]).addTo(map.value)
})

watch([() => props.lat, () => props.lng], () => {
  if (marker.value && map.value) {
    marker.value.setLatLng([props.lat, props.lng])
    map.value.setView([props.lat, props.lng], 13)
  }
})

onUnmounted(() => {
  if (map.value) {
    map.value.remove()
    map.value = null
    marker.value = null
  }
})
</script>

<template>
  <div class="relative h-96 w-full" ref="mapContainer"></div>
</template>

<style scoped></style>

内容的提问来源于stack exchange,提问作者Ricardo de Paula

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 00:37:08