Vuejs 传单:未找到地图容器

Kev*_*vin 7 javascript leaflet vue.js

我正在尝试在 Vue 中使用传单地图,但不断收到错误消息:

未捕获的错误:未找到地图容器。

这是我的组件的样子:

<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>
Run Code Online (Sandbox Code Playgroud)

我还在index.html脑海中添加了 Leaflet CSS 和 JavaScript 。

ghy*_*ybs 9

欢迎来到 SO!

当您尝试通过传递 Element id ( L.map('mapid'))来实例化 Leaflet Map 时,问题在于您的 Vue 组件尚未附加到您的页面 DOM。因此,当 Leaflet 尝试查询后者以找到您的 Element 时,它找不到它,因此您会收到错误消息。

如果您尝试在mounted生命周期钩子中实例化,同样的事情:您的 Vue 组件实例已创建并构建其片段 HTML 结构,但仍未附加到页面 DOM。

但是,您可以直接传递您的 Element,而不是传递您的 Element id。请注意,您仍然需要在mounted钩子中这样做,以确保您的组件实例确实具有构建的 HTML 结构。

L.map(<HTMLElement> el, <Map options> options?)
Run Code Online (Sandbox Code Playgroud)

在给定<div>HTML 元素的实例和可选的对象文字的情况下实例化地图对象Map options

然后要获取您的元素,只需利用 Vue$refs实例属性和ref特殊属性,如 Vue 指南 >访问子组件实例和子元素中所述

[…] 有时您可能仍然需要直接访问 JavaScript 中的子组件。为此,您可以使用该ref属性为子组件分配一个引用 ID 。

因此,在您的情况下,您的模板中会有:

L.map(<HTMLElement> el, <Map options> options?)
Run Code Online (Sandbox Code Playgroud)

在您的组件脚本中:

<div id="mapid" ref="mapElement"></div>
Run Code Online (Sandbox Code Playgroud)

与 HTML id 相比,使用 Vue ref 的额外优势是您可以拥有多个带有自己映射的 Vue 组件实例,并且 Vue 会将适当的 Element 引用到每个脚本。

而对于 HTML id,如果您有多个具有相同 id 的地图元素,则每次您尝试实例化地图时,Leaflet 只会获得第一个,从而引发地图已为此容器初始化的错误。