Рендеринг дочерних элементов с помощью LitElement (light DOM и слотов)

#children #lit-element #slot

#дочерние элементы #lit-элемент #слот

Вопрос:

Я пытаюсь написать веб-компонент LitElement, который будет переносить неизвестный дочерний контент. Я читал о слотах ( https://lit-element.readthedocs.io/en/v0.6.4/docs/templates/slots / ) но, похоже, это работает только для теневого DOM. Я использую light DOM. В React свойства поставляются со специальным свойством ‘children’ для рендеринга дочернего дерева. Но как это может быть достигнуто в LitElement в light DOM? Несмотря на то, что в приведенной выше документации говорится о light DOM, в моем случае это не работает.

ОБНОВЛЕНИЕ: я пытаюсь обойти это, добавив свойство типа ‘templateResult’ к моему элементу и передав содержимое в качестве свойства. Но не уверен, что это лучшее решение.

Комментарии:

1. Не могли бы вы опубликовать свой код и любое сообщение об ошибке, пожалуйста?

2. Кстати, официальный сайт здесь lit-element.polymer-project.org/guide/templates#slots

Ответ №1:

В light Dom ваш render() изменит предыдущие дочерние узлы, которые были у вашего компонента до монтирования.

Одним из подходов может быть сохранение всего, что было до вызова connectedCallback .

Рассмотрим следующий пример

 export class Text extends LitElement {
  createRenderRoot() {
    return this;
  }

  connectedCallback() {
    super.connectedCallback();
    this._textOverride = this.innerText.trim();
  }
  render() {
    return html`
      <strong>${this._textOverride}</strong>
    `;
  }
}
 

Ответ №2:


для рендеринга элементов непосредственно в дереве DOM (он же light-dom) в Lit версии 2 используйте render exported from lit/html.js (lit импортирует его из своей версии lit-html, подробности см. В разделе https://lit.dev /):

 <script type=module>
// or from 'lit' and 'lit/html.js' respectively:
import { LitElement, html } from 'https://unpkg.com/lit?module';
import { render } from 'https://unpkg.com/lit/html.js?module';

class EgTime extends LitElement{
    connectedCallback(){
        super.connectedCallback();
        render(this.time(), this);
    }
    time(){
        const now = new Date();
        return html`<time datetime="${ now.toISOString() }">time ${ now.toLocaleTimeString() } ${ now.toLocaleDateString() }</time>`;
    }
    render(){
        return html`<hr> ::slotted( <slot>~~~</slot> ) <hr>`;
    }
}

customElements.define('eg-time', EgTime);
</script>
<eg-time style="position:fixed;inset:auto 3rem 3rem auto;background:#fff;padding:1rem;border:1px solid #000;">
...
</eg-time>