問題描述
我正在嘗試在 Vue 中使用傳單地圖,但不斷收到錯誤消息:
<塊引用>未捕獲的錯誤:未找到地圖容器.
這是我的組件的樣子:
<template><div id="app" class="container">地圖<div class="col-md-9"><div id="mapid"></div></div></div></模板><樣式范圍>#mapid {高度:800px;}</風格><腳本>從傳單"導入 Lvar 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: '地圖數據和副本;<a >OpenStreetMap</a>貢獻者,<a >CC-BY-SA</a>,圖像 ? <a mapbox.streets',訪問令牌:''}).addTo(mymap);</腳本>
我還在 index.html
頭中添加了 Leaflet CSS 和 JavaScript.
歡迎來到 SO!
當您嘗試實例化您的傳單地圖時通過傳遞您的元素 ID (L.map('mapid')
),問題是你的 Vue 組件還沒有附加到你的頁面 DOM.因此,當 Leaflet 嘗試查詢后者以找到您的元素時,它找不到它,因此您的錯誤消息.
如果你嘗試在 mounted
生命周期鉤子中實例化,同樣的事情:你的 Vue 組件實例被創建并且它的片段 HTML 結構被構建,但仍然沒有附加到頁面 DOM.
但是,您可以直接傳遞您的 Element,而不是傳遞您的 Element id.請注意,您仍然需要在 mounted
掛鉤中這樣做,以確保您的組件實例確實具有構建的 HTML 結構.
L.map(<HTMLElement> el, <地圖選項> 選項?)
<塊引用>
在給定 <div>
HTML 元素的實例和可選的帶有 Map options
的對象文字的情況下實例化地圖對象.
然后要獲取您的元素,只需利用 Vue $refs
實例屬性和 ref
特殊屬性,如中所述Vue 指南 > 訪問子級組件實例和子元素:
[...] 有時您可能仍需要在 JavaScript 中直接訪問子組件.為此,您可以使用 ref
屬性為子組件分配一個引用 ID.
因此,在您的情況下,您的模板中有:
<div id="mapid" ref="mapElement"></div>
在你的組件腳本中:
從'leaflet'導入L導出默認 {掛載(){var mymap = L.map(this.$refs['mapElement']).setView([51.505, -0.09], 13);//等等.},}
使用 Vue ref 而不是 HTML id 的額外優勢是您可以擁有多個 Vue 組件實例和它們自己的映射,并且 Vue 會為每個腳本引用適當的元素.
而對于 HTML id,如果您有多個具有相同 id 的地圖元素,每次您嘗試實例化地圖時,Leaflet 只會獲得第一個,從而引發地圖已為此容器初始化的錯誤.
I am trying to use the leaflet map in Vue, but keep getting the error:
Uncaught Error: Map container not found.
This is what my component looks like:
<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 >OpenStreetMap</a> contributors, <a >CC-BY-SA</a>, Imagery ? <a ,
maxZoom: 18,
id: 'mapbox.streets',
accessToken: ''
}).addTo(mymap);
</script>
I have also added the Leaflet CSS and JavaScript under that in my index.html
head.
Welcome to SO!
When you try instantiating your Leaflet Map by passing it your Element id (L.map('mapid')
), the problem is that your Vue component is not yet attached to your page DOM. Therefore when Leaflet tries to query the latter to find your Element, it cannot find it, hence your error message.
Same thing if you try instantiating in the mounted
lifecycle hook: your Vue component instance is created and its fragment HTML structure is built, but still not attached to the page DOM.
But instead of passing your Element id, you can directly pass your Element. Note that you still need to do so in the mounted
hook, to ensure that your component instance does have an HTML structure built.
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
.
Then to get your Element, simply leverage Vue $refs
instance property and ref
special attribute, as described in Vue Guide > Accessing Child Component Instances & Child Elements:
[…] 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.
Therefore in your case you would have in your template:
<div id="mapid" ref="mapElement"></div>
And in your component script:
import L from 'leaflet'
export default {
mounted() {
var mymap = L.map(this.$refs['mapElement']).setView([51.505, -0.09], 13);
// etc.
},
}
The added advantage of using Vue ref over HTML id is that you can have several Vue component instances with their own map, and Vue will reference the appropriate Element to each script.
Whereas with HTML id, if you have several map Elements with same id, Leaflet will get only the first one every time you try to instantiate your map, raising the error that the map is already initialized for this container.
這篇關于Vuejs Leaflet:找不到地圖容器的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!