LitElement中的单张使用
我当前正在使用LitElement组件开发一个应用程序。我想把传单整合进去,在显示地图方面有问题。我已经在我的NPM项目中安装了传单,并创建了一个如下所示的类。
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’。
我对如何使用宣传单在我的LitElement应用程序中显示地图有点迷惑,如果能推动我朝着正确的方向前进,我将感激不尽。
解决方案
对于LIT项目,我们倾向于建议人们坚持使用ES模块导入(虽然这是可选的)。因此,不是从
导入import './node_modules/leaflet/dist/leaflet';
改为尝试:
import {map as createMap, tileLayer} from './node_modules/leaflet/dist/leaflet-src.esm.js';
这是因为它通常更符合Web组件的模块化特性,而且捆绑程序可以比调用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才能正常工作的库在使用影子DOM作为影子根作用域DOM的Web组件中往往会出现问题,从而查询到它们的根。不过,幸运的是,leaflet's documentation表明我们可以将元素引用而不仅仅是id传递给它。这意味着我们需要如下获取元素引用:
const mapEl = this.shadowRoot.querySelector('#mapid');
然后我们可以将其传递给createMap
函数
const mapEl = this.shadowRoot.querySelector('#mapid');
let map = createMap(mapEl).setView([51.505, -0.09], 13);
最后我们会看到我们遇到了mapEl
是null
的问题。这是因为LitElement在firstUpdated
lifecycle callback之前不会呈现其内容。这意味着我们必须将地图创建位置从connectedCallback
更改为firstUpdated
。
以下是您的代码的一个工作示例,我还在其中添加了一些样式,以使自定义元素具有一定的高度:https://jsbin.com/fumusodake/edit?html,output
相关文章