带有appendChild的LitElement插槽不起作用

问题描述 投票:2回答:2

[当我尝试在我的LitElement组件上添加slot child时,它不起作用,也不接受创建它。

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);
    };
  }
javascript html lit-element lit-html
2个回答
2
投票

该元素是Web组件技术套件的一部分,是Web组件内的占位符,您可以使用自己的标记来填充该占位符,该标记使您可以创建单独的DOM树并将它们一起显示。

您的代码正确,但是您等待其他行为您在DOM中等待Spot元素,但是没有出现Spot,因为您没有在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
投票

虽然我个人不建议您为可以实现的Web组件动态创建插槽,但是只需要将创建代码保留在render函数中即可

例如,您可以从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

Here's a live demo

由于您之前的代码无法按预期工作的原因,LitElement大部分希望您将与模板相关的代码保留在render函数中,因为使用appendChild或类似的DOM函数添加的任何内容都会得到下次组件更新时“删除”,因此您必须在每次更新后自行添加它]

通过直接在render方法中添加插槽,可以确保不会以意外的方式删除插槽

© www.soinside.com 2019 - 2024. All rights reserved.