Слот LitElement с appendChild не работает - PullRequest
2 голосов
/ 30 сентября 2019

Когда я попытался добавить дочерний слот на свой компонент в LitElement, он не работает и не принял его создание.

render() {
    return html `<div class="wizard-container ${this.className}"></div>`;
  }

  firstUpdated() {
    let wizardContainer = this.shadowRoot.querySelector('.wizard-container');
    for (let i = 0; i < this.steps; i++) {
      let slot = document.createElement('SLOT');
      slot.setAttribute('name', 'step_' + (i + 1))
      wizardContainer.appendChild(slot);
    };
  }

Ответы [ 2 ]

2 голосов
/ 30 сентября 2019

Элемент - часть набора технологий Web Components - является заполнителем внутри веб-компонента, который можно заполнить собственной разметкой, которая позволяет создавать отдельные деревья DOM и представлять их вместе.

ваш кодэто правильно, но вы ожидаете другого поведения, вы ожидаете элементы spot в вашей DOM, но пятно не появится, потому что вы не вводили никаких данных в ваше spot, когда вы пытаетесь использовать spot в вашем компоненте, это будет работать правильно, просто попробуйте

<element-details>
  <span slot="element-name">slot</span>
  <span slot="description">A placeholder inside a web
    component that users can fill with their own markup,
    with the effect of composing different DOM trees
    together.</span>
  <dl slot="attributes">
    <dt>name</dt>
    <dd>The name of the slot.</dd>
  </dl>
</element-details>
2 голосов
/ 30 сентября 2019

Хотя я лично не рекомендую вам динамически создавать слоты для веб-компонента, которого вы можете достичь, вам просто нужно сохранить код создания в функции рендеринга

Например, вы можете создать массивиз вашей переменной steps и итерируйте ее, используя функцию map, чтобы создать слоты, подобные этому:

render() {
  return html`<div class="wizard-container ${this.className}">
    ${Array.from({ length: this.steps }, (v, k) => k).map(
      item =>
        html`<slot name="step_${item}"><div>Default content ${item}</div></slot>`
    )}
  </div>`;
}

, а затем используйте ваш компонент следующим образом:

<my-element steps="3">
  <div slot="step_1">Custom content</div>
</my-element>

, которыйможет привести к чему-то вроде:

Содержимое по умолчанию 0 Пользовательское содержимое Содержимое по умолчанию 2

Вот демонстрационная версия

Что касается причины, по которой ваш предыдущий кодне работает так, как вы ожидали, LitElement по большей части ожидает, что вы сохраните код, связанный с шаблонами, в функции рендеринга, поскольку все, что вы добавляете с помощью appendChild или аналогичных функций DOM, будет «удалено» при следующем обновлении компонента, поэтомувам придется добавлять его после каждого обновления самостоятельно

Добавляя слоты непосредственно в метод рендеринга, вы гарантируете, что они не получатизбрал неожиданным образом

...