LitElement 中的传单用法
Leaflet usage in LitElement
我目前正在开发一个使用 LitElement 组件的应用程序。我想将 Leaflet 集成到其中,但在显示地图时遇到问题。我已经使用 npm 在我的项目中安装了 Leaflet,并创建了一个看起来像这样的 class。
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);
运行 我的应用程序导致以下错误:Uncaught TypeError: Cannot set 属性 'L' of undefined。
我对如何使用 Leaflet 在我的 LitElement 应用程序中显示地图有点迷茫,感谢您向正确的方向推进。
对于 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 才能运行的库往往会在使用影子 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
我目前正在开发一个使用 LitElement 组件的应用程序。我想将 Leaflet 集成到其中,但在显示地图时遇到问题。我已经使用 npm 在我的项目中安装了 Leaflet,并创建了一个看起来像这样的 class。
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);
运行 我的应用程序导致以下错误:Uncaught TypeError: Cannot set 属性 'L' of undefined。 我对如何使用 Leaflet 在我的 LitElement 应用程序中显示地图有点迷茫,感谢您向正确的方向推进。
对于 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 才能运行的库往往会在使用影子 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