Lit:如何在自定义元素中监听反射属性变更并更新
监听my-select的option-checked属性变更的实现方式
针对你的场景,有几种实用的方法可以在my-form里监听my-select的option-checked属性变更:
方法1:用MutationObserver监听属性变化
通过Lit的@query装饰器拿到my-select的实例,然后在元素首次更新后创建MutationObserver,专门监听option-checked属性的变化,避免不必要的性能消耗。
代码示例:
import { customElement, LitElement, html, query } from 'lit'; import { MySelect } from './my-select'; @customElement('my-form') export class MyForm extends LitElement { @query('my-select') private mySelect!: MySelect; private observer?: MutationObserver; // 其他业务代码... firstUpdated() { // 创建属性变化观察者 this.observer = new MutationObserver((mutations) => { mutations.forEach(mutation => { if (mutation.attributeName === 'option-checked') { const newValue = this.mySelect.getAttribute('option-checked'); this.handleOptionChange(newValue); } }); }); // 只监听option-checked属性的变化 this.observer.observe(this.mySelect, { attributes: true, attributeFilter: ['option-checked'] }); } disconnectedCallback() { super.disconnectedCallback(); // 组件销毁时清理观察者,防止内存泄漏 this.observer?.disconnect(); } private handleOptionChange(newValue: string | null) { // 在这里写你的更新逻辑 console.log('选中项变更为:', newValue); // 比如更新表单数据、触发校验等操作 } render() { return html` <my-select .options=${this.options} option-checked="foo" ></my-select> `; } }
方法2:监听自定义元素的属性变更事件
如果能修改my-select的代码,推荐在它的属性变更时主动派发一个自定义事件,这种方式比MutationObserver更高效,也更符合自定义元素的设计规范。
先修改my-select的代码,在attributeChangedCallback里添加事件派发:
// my-select.ts中的代码片段 attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null) { super.attributeChangedCallback(name, oldValue, newValue); if (name === 'option-checked' && oldValue !== newValue) { this.dispatchEvent(new CustomEvent('option-checked-changed', { detail: { value: newValue }, bubbles: true, composed: true // 允许事件穿透Shadow DOM })); } }
然后在my-form里直接监听这个事件:
@customElement('my-form') export class MyForm extends LitElement { // 其他业务代码... private handleOptionChange(e: CustomEvent) { const newValue = e.detail.value; console.log('选中项变更为:', newValue); // 执行你的更新操作 } render() { return html` <my-select .options=${this.options} option-checked="foo" @option-checked-changed=${this.handleOptionChange} ></my-select> `; } }
方法3:通过双向绑定同步属性值
如果my-select的option-checked是Lit的响应式属性,还可以用双向绑定的方式,让my-form的属性和my-select的属性自动同步,属性变化时触发updated钩子执行逻辑。
代码示例:
import { customElement, LitElement, html, property } from 'lit'; @customElement('my-form') export class MyForm extends LitElement { @property({ type: String }) optionChecked = 'foo'; // 其他业务代码... updated(changedProperties) { if (changedProperties.has('optionChecked')) { // 当属性变化时执行更新逻辑 console.log('选中项变更为:', this.optionChecked); // 比如提交表单、更新其他关联组件等 } } render() { return html` <my-select .options=${this.options} .optionChecked=${this.optionChecked} @option-checked-changed=${(e: CustomEvent) => this.optionChecked = e.detail.value} ></my-select> `; } }
这种方式需要my-select同样派发option-checked-changed事件,和方法2的前置条件一致。
内容的提问来源于stack exchange,提问作者dbj44
相关产品推荐
相关产品推荐

