Web Components 中如何正确传递属性值?
我用 Web Components 写了一个自定义元素,想通过 HTML 属性传值进去,但组件内部好像拿不到最新的值。比如我写了 <my-button label="提交">,但在 connectedCallback 里读 this.getAttribute(‘label’) 却是 null,这是为啥?
我试过在 constructor 里读,也不行。是不是得用 observedAttributes 配合 attributeChangedCallback?但我加上之后还是没触发,代码大概是这样:
class MyButton extends HTMLElement {
static get observedAttributes() {
return ['label'];
}
attributeChangedCallback(name, oldValue, newValue) {
console.log('changed', newValue);
}
connectedCallback() {
console.log('attr:', this.getAttribute('label'));
}
}
customElements.define('my-button', MyButton);
问题出在生命周期上。我们先看正确的完整代码:
分步解释原因:
第一步,constructor里拿不到属性是因为这时候元素还没被插入DOM,属性还没被设置。这是Web Components的标准行为。
第二步,observedAttributes必须配合attributeChangedCallback使用。你漏掉了关键点:attributeChangedCallback只会在属性从null变成有值时触发(比如从null变成"提交"),但不会在属性值从undefined变成null时触发。
第三步,connectedCallback是最稳妥的地方,这时候DOM已经完成挂载,一定能拿到初始属性值。
实际使用时的正确姿势:
几个容易忽略的细节:
1. 在constructor里调用getAttribute基本都会返回null
2. 属性名要完全匹配(比如label和data-label是不同的)
3. 用setAttribute修改值才会触发回调,直接修改property不会
如果还不行,检查下是不是拼写错了observedAttributes里的属性名,我当初因为这个debug了半小时...