Vuejs Leaflet:找不到地图容器 [英] Vuejs Leaflet : Map Container Not Found

查看:23
本文介绍了Vuejs Leaflet:找不到地图容器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在 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 href="https://www.openstreetmap.org/">OpenStreetMap</a>贡献者,<a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>,图像 © <a href="https://www.mapbox.com/">Mapbox</a>',最大缩放:18,id: '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 &copy; <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>

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 with Map 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:找不到地图容器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆