LitElement 使用按钮附加自定义元素
LitElement appending custom elements using button
我有一个自定义的 LitElement,在它里面,我需要有一个按钮,可以在容器内动态添加新的自定义元素(最好使用 html 函数生成的 TemplateResult 对象):
import { LitElement, html, render } from "lit";
import { customElement } from "lit/decorators.js";
@customElement('example-custom-component')
class CustomComponent extends LitElement {
render() {
return html`
<div id="custom-el-container">
</div>
<button @click=${this.appendNewCustomEl}>click me!</button>
`;
}
appendNewCustomEl() {
const templateToAppend = html`
<another-custom-component>
some other things added here
</another-custom-component>
`;
render(templateToAppend, this.shadowRoot?.querySelector('#custom-el-container'));
}
}
正如您在上面看到的,我试图通过使用渲染函数来实现它,但我没有将它附加到容器的末尾,而是简单地覆盖了 div 的内容。我究竟做错了什么?实现这些结果的最佳方法是什么?请帮忙
编辑:
关于点击事件的评论中我的问题的新示例:
appendNewCustomEl() {
this.shadowRoot!.querySelector('#custom-el-container').insertAdjacentHTML("beforeend", `
<another-custom-component>
<button @click=${this.functionFromCustomComponent}>click me!</button>
</another-custom-component>
`)
}
如果你真的想用 lit-html 来做,并且你的容器内容纯粹是你在每次点击按钮时动态呈现的内容,(即不是服务器端呈现的内容)或者你正在使用 lit-html v2 然后你可以有一个列表并跟踪你渲染的内容。类似于:
items=[];
appendNewCustomEl() {
this.items.push(null);
const templatesToAppend = this.items.map(() => html`
<another-custom-component>
some other things added here
</another-custom-component>
`);
render(templatesToAppend, this.shadowRoot?.querySelector('#custom-el-container'));
}
一般来说,lit-html 擅长并试图实现的是仅更改部分时的最佳 re-render 标记。不需要模板引擎替代车把、小胡子和 co.
在你的例子中,你不需要它,不需要 lit-html:
appendNewCustomEl() {
this.shadowRoot!.querySelector('#custom-el-container').insertAdjacentHTML("beforeend", `
<another-custom-component>
some other things added here
</another-custom-component>
`)
}
我稍微修改了您的示例代码,使其更加地道。与其使用 querySelector 和 insertAdjacentHTML
,不如以声明方式呈现模板数组。这有一个额外的好处,即您的 functionFromCustomComponent
事件绑定“正常工作”。
我写了完整的例子in a Lit playground。
模板列表存储在 reactive property、this.templates
中,每当更新列表时都会安排高效更新。
然后 this.appendNewCustomEl
方法可以将新模板推送到列表,自动高效渲染会自动发生。
this.templates
使用表达式呈现为 #custom-el-container
div:
<div id="custom-el-container">
${this.templates}
</div>
有关其他示例,请参阅 Lit expressions documentation。
在我的链接示例中,单击时模板列表变为蓝色以演示事件工作。
不是必需的,但相关,Lit.dev 有一个关于 Working with lists 的教程,如果你好奇的话,它会更深入。
我有一个自定义的 LitElement,在它里面,我需要有一个按钮,可以在容器内动态添加新的自定义元素(最好使用 html 函数生成的 TemplateResult 对象):
import { LitElement, html, render } from "lit";
import { customElement } from "lit/decorators.js";
@customElement('example-custom-component')
class CustomComponent extends LitElement {
render() {
return html`
<div id="custom-el-container">
</div>
<button @click=${this.appendNewCustomEl}>click me!</button>
`;
}
appendNewCustomEl() {
const templateToAppend = html`
<another-custom-component>
some other things added here
</another-custom-component>
`;
render(templateToAppend, this.shadowRoot?.querySelector('#custom-el-container'));
}
}
正如您在上面看到的,我试图通过使用渲染函数来实现它,但我没有将它附加到容器的末尾,而是简单地覆盖了 div 的内容。我究竟做错了什么?实现这些结果的最佳方法是什么?请帮忙
编辑: 关于点击事件的评论中我的问题的新示例:
appendNewCustomEl() {
this.shadowRoot!.querySelector('#custom-el-container').insertAdjacentHTML("beforeend", `
<another-custom-component>
<button @click=${this.functionFromCustomComponent}>click me!</button>
</another-custom-component>
`)
}
如果你真的想用 lit-html 来做,并且你的容器内容纯粹是你在每次点击按钮时动态呈现的内容,(即不是服务器端呈现的内容)或者你正在使用 lit-html v2 然后你可以有一个列表并跟踪你渲染的内容。类似于:
items=[];
appendNewCustomEl() {
this.items.push(null);
const templatesToAppend = this.items.map(() => html`
<another-custom-component>
some other things added here
</another-custom-component>
`);
render(templatesToAppend, this.shadowRoot?.querySelector('#custom-el-container'));
}
一般来说,lit-html 擅长并试图实现的是仅更改部分时的最佳 re-render 标记。不需要模板引擎替代车把、小胡子和 co.
在你的例子中,你不需要它,不需要 lit-html:
appendNewCustomEl() {
this.shadowRoot!.querySelector('#custom-el-container').insertAdjacentHTML("beforeend", `
<another-custom-component>
some other things added here
</another-custom-component>
`)
}
我稍微修改了您的示例代码,使其更加地道。与其使用 querySelector 和 insertAdjacentHTML
,不如以声明方式呈现模板数组。这有一个额外的好处,即您的 functionFromCustomComponent
事件绑定“正常工作”。
我写了完整的例子in a Lit playground。
模板列表存储在 reactive property、this.templates
中,每当更新列表时都会安排高效更新。
然后 this.appendNewCustomEl
方法可以将新模板推送到列表,自动高效渲染会自动发生。
this.templates
使用表达式呈现为 #custom-el-container
div:
<div id="custom-el-container">
${this.templates}
</div>
有关其他示例,请参阅 Lit expressions documentation。
在我的链接示例中,单击时模板列表变为蓝色以演示事件工作。
不是必需的,但相关,Lit.dev 有一个关于 Working with lists 的教程,如果你好奇的话,它会更深入。