Vuejs Leaflet:未找到地图容器
我正在尝试在 Vue 中使用 Leaflet 地图,但一直出现错误:
Uncaught Error: Map container not found.
这是我的组件的样子:
<template>
<div id="app" class="container">
Map
<div class="col-md-9">
<div id="mapid"></div>
</div>
</div>
</template>
<style scoped>
#mapid {
height: 800px;
}
</style>
<script>
import L from 'leaflet'
var mymap = L.map('mapid').setView([51.505, -0.09], 13);
L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={}', {
attribution: 'Map data © <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
maxZoom: 18,
id: 'mapbox.streets',
accessToken: ''
}).addTo(mymap);
</script>
我还在我的
index.html
头中添加了 Leaflet CSS 和 JavaScript。
欢迎来到 SO!
当您尝试
通过传递您的元素 id
(
L.map('mapid')
) 来实例化您的 Leaflet Map 时,问题是您的 Vue 组件尚未附加到您的页面 DOM。因此,当 Leaflet 尝试查询后者以查找您的元素时,它找不到它,因此出现错误消息。
如果您尝试在
mounted
生命周期钩子中实例化,也会发生同样的事情:您的 Vue 组件实例已创建并且其片段 HTML 结构已构建,但仍未附加到页面 DOM。
但是,您可以直接传递元素,而不是传递元素 id。请注意,您仍然需要在
mounted
钩子中执行此操作,以确保您的组件实例确实具有构建的 HTML 结构。
L.map(<HTMLElement> el, <Map options> options?)
Instantiates a map object given an instance of a
<div>
HTML element and optionally an object literal withMap options
.
然后要获取您的元素,只需利用 Vue
$refs
实例属性和
ref
特殊属性,如 Vue 指南 > 中所述
访问子组件实例 &子元素
:
[…] sometimes you might still need to directly access a child component in JavaScript. To achieve this you can assign a reference ID to the child component using the
ref
attribute.
因此,在您的情况下,您的模板中应该有:
<div id="mapid" ref="mapElement"></div>
在您的组件脚本中:
import L from 'leaflet'
export default {
mounted() {
var mymap = L.map(this.$refs['mapElement']).setView([51.505, -0.09], 13);
// etc.
},
}
使用 Vue ref 而不是 HTML id 的额外优势是,您可以拥有多个具有自己地图的 Vue 组件实例,并且 Vue 将引用每个脚本的相应元素。
而使用 HTML id,如果您有多个具有相同 id 的地图元素,每次您尝试实例化地图时,Leaflet 只会获取第一个,从而引发错误,提示该容器的地图已初始化。