Lit自定义进度条组件构造函数无法获取HTML属性值如何解决
问题解决方案
核心原因
Lit组件的constructor执行阶段仅完成实例的基础初始化,此时组件还未被插入DOM树,HTML上声明的自定义属性还未被解析映射到你定义的组件properties上,所以直接调用main()时count、display等属性都是初始默认值,逻辑自然无法正常运行。你之前加setTimeout是通过延时等待属性解析完成的hack方案,稳定性差,不推荐生产环境使用。
正确处理方式
使用Lit内置的firstUpdated生命周期钩子,该钩子会在组件第一次完成渲染、所有声明的properties都完成初始化赋值后触发,是启动倒计时逻辑的最佳时机。
同时建议补充定时器清理逻辑,避免组件卸载后出现内存泄漏。
修改后完整代码
JS代码(main.js)
import { LitElement, html } from "lit"; class ProgressBar extends LitElement { static get properties() { return { count: { type: Number }, width: { type: Number }, color: { type: String }, colorback: { type: String }, display: { type: String }, }; } render() { let output = ""; if (this.display === "true") { output = html` <style> :host > div { background-color: ${this.colorback}; width: 100%; } :host > div > div { background-color: ${this.color}; width: ${this.width}%; height: 30px; } </style> <div> <div></div> </div> `; } return output; } draw() { const x = this._date_end - Date.now(); this.width = (x * 100) / this.count; if (this.width > 0) { // 存储定时器ID用于后续清理 this._timer = setTimeout(() => this.draw(), 1000 / 60); } else { this.width = 0; } } main() { this._date_end = new Date(Date.now() + this.count); this.draw(); } constructor() { super(); // 删掉原来的setTimeout和直接调用main的逻辑 } // 新增生命周期钩子,属性初始化完成后自动触发 firstUpdated() { this.main(); } // 新增组件卸载逻辑,清理定时器避免内存泄漏 disconnectedCallback() { super.disconnectedCallback(); if (this._timer) { clearTimeout(this._timer); } } } window.customElements.define("progress-bar", ProgressBar);
HTML代码无需修改,保持原有写法即可。
可选优化
可以将display属性的类型修改为Boolean,使用更便捷:
static get properties() { return { // 其他属性不变 display: { type: Boolean }, }; }
对应的HTML写法可以简化为:
<progress-bar display width="100" color="#4cAf50" colorback="#ddd" count="5000" > </progress-bar>
内容的提问来源于stack exchange,提问作者ZiTAL
相关产品推荐
相关产品推荐

