开发者问题收集

LitElement 中的 Leaflet 使用

2021-03-12
974

我目前正在开发一个使用 LitElement 组件的应用程序。我想将 Leaflet 集成到其中,但在显示地图时遇到了问题。我已经使用 npm 在我的项目中安装了 Leaflet,并创建了一个如下所示的类。

import {LitElement, html, css} from 'lit-element';
import './node_modules/leaflet/dist/leaflet';

class Map extends LitElement{

    static get styles() {
        return [css``];
    }

    constructor() {
        super();
    }
    connectedCallback() {
        super.connectedCallback();
        let map = L.map('mapid').setView([51.505, -0.09], 13);

        let urlTemplate = 'http://{s}.tile.osm.org/{z}/{x}/{y}.png';
        map.addLayer(L.tileLayer(urlTemplate, {minZoom: 4}));
    }

    render() {
        return html`
            <link rel="stylesheet" href="./node_modules/leaflet/dist/leaflet.css">
            <div id="mapid" style="height: 100%"></div>

        `;
    }
}

customElements.define("my-map", Map);

运行我的应用程序导致以下错误:未捕获的 TypeError:无法设置未定义的属性“L”。 我有点不知道如何使用 Leaflet 在我的 LitElement 应用程序中显示地图,如果能给我指明正确的方向,我将不胜感激。

1个回答

对于 Lit 项目,我们倾向于建议人们坚持使用 es-module 导入(但这是可选的)。因此,不要从

import './node_modules/leaflet/dist/leaflet';

导入,而是尝试:

import {map as createMap, tileLayer} from './node_modules/leaflet/dist/leaflet-src.esm.js';

这是因为它通常更适合 webcomponents 的模块化特性,并且 es 模块可以通过捆绑器比调用 window.L

更有效地进行优化,接下来,重写此语法的传单调用。例如

let map = L.map('mapid').setView([51.505, -0.09], 13);

// should be
let map = createMap('mapid').setView([51.505, -0.09], 13);

// and
map.addLayer(L.tileLayer(urlTemplate, {minZoom: 4}))

// should be
map.addLayer(tileLayer(urlTemplate, {minZoom: 4}))

接下来,需要全局 ID 才能运行的库往往会在使用 shadow DOM 作为 Shadow Roots 范围 DOM 的 Web 组件中出现问题,从而查询其根。不过,幸运的是, leaflet 的文档 显示,我们可以向其传递元素引用,而不仅仅是 id。这意味着我们需要像这样获取元素引用:

const mapEl = this.shadowRoot.querySelector('#mapid');

然后我们可以将其传递给 createMap 函数

const mapEl = this.shadowRoot.querySelector('#mapid');
let map = createMap(mapEl).setView([51.505, -0.09], 13);

最后,我们会发现我们遇到了 mapElnull 的问题。这是因为 LitElement 直到 firstUpdated 生命周期回调 才会呈现其内容。这意味着我们必须将地图创建的位置从 connectedCallback 更改为 firstUpdated

下面是您的代码的一个工作示例,其中我还添加了一些样式以赋予自定义元素一些高度: https://jsbin.com/fumusodake/edit?html,output

TechyTaco
2021-03-12