我遇到了一些奇怪的问题,其中具有 Property Expression (
.checked
) 的 Lit Web 组件未更新。这是Lit Playground的简单复制:
import {html, css, LitElement} from 'lit';
import {customElement, property} from 'lit/decorators.js';
@customElement('simple-greeting')
export class SimpleGreeting extends LitElement {
static styles = css`p { color: blue }`;
@property()
selected = false;
render() {
debugger;
return html`<input type="checkbox"
.checked=${this.selected}
@change=${this.handleChange} />`;
}
handleChange(e) {
this.selected = e.target.checked;
this.dispatchEvent(new Event("change"));
}
}
和 HTML:
<simple-greeting></simple-greeting>
<script>
const chk = document.querySelector("simple-greeting");
chk.addEventListener("change", () => {
console.log(chk.selected);
chk.selected = false;
});
</script>
在这里,每次我单击复选框时,值始终是
true, false, true, false, true, false, ...
而不是 true
,因为代码应该将其恢复为 false。 (如果有人问我为什么这样做,在实际场景中,如果不满足某些条件,我的复选框将被恢复)。
调试时,
render()
被正确调用,并且selected
的值为false
(这是正确的)。然而,结果 DOM 元素仍然有一半的时间 checked
为 true。
上面的截图:
selected
是false
,但是渲染的复选框($0
指向复选框,而不是组件)$0.checked
仍然是true
。
这里有什么问题?
编辑添加以防它有助于更轻松地解决问题,如果我在单独的框架中更新属性,则问题不会发生:
requestAnimationFrame(() => chk.selected = false);
如点燃的文档中所述
无论如何,如果您想用绑定值覆盖 DOM 值,请使用
live()
指令
import {html, css, LitElement} from 'lit';
import {customElement, property} from 'lit/decorators.js';
import {live} from 'lit/directives/live.js';
@customElement('simple-greeting')
export class SimpleGreeting extends LitElement {
static styles = css`p { color: blue }`;
@property()
selected = false;
render() {
console.log(this.selected,'Render');
return html`<input type="checkbox"
?checked=${live(this.selected)}
@change=${this.handleChange} />`;
}
handleChange(e) {
this.selected = e.target.checked;
this.dispatchEvent(new Event("change"));
}
}