你的前端框架要被 Web 组件取代了(5)
const element = document.querySelector('my-element');element.doSomething();
你在元素上定义的任何方法都将成为其公共 JavaScript API 的一部分。这样一来,你就可以通过为元素的属性提供 setter 来实现数据绑定,这样它就可以在元素的 HTML 中呈现属性值,诸如此类。由于除了字符串之外不能为属性赋予任何其他值,因此像对象这样的复杂值应作为属性传递给自定义元素。
除了声明一个 Web 组件的初始状态之外,attribute 属性还能用来映射相关 property 属性的值,以便将元素的 JavaScript 状态映射到其 DOM 表达中。一个例子是 input 元素的 disabled 属性:
<input name="name"> const input = document.querySelector('input');input.disabled = true;
将输入的属性 disabled property 设置为 true 后,此更改将映射到相关的 disabled attribute 属性上:
<input name =“name”disabled>
使用 setter 就能将一个 property 映射到一个 attribute 属性上:
class MyElement extends HTMLElement { ... set disabled(isDisabled) { if(isDisabled) { this.setAttribute('disabled', ''); } else { this.removeAttribute('disabled'); } } get disabled() { return this.hasAttribute('disabled'); }}
如果需要在属性更改时执行某些操作,请将其添加到 observedAttributes 数组中。为提升性能,这里只会观察此处列出的属性以进行更改。一旦属性的值发生变动,就将使用属性的名称、其当前值及其新值调用 attributeChangedCallback:
class MyElement extends HTMLElement { static get observedAttributes() { return ['disabled']; } constructor() { const shadowRoot = this.attachShadow({mode: 'open'}); shadowRoot.innerHTML = ` <style> .disabled { opacity: 0.4; } </style> <div id="container"></div> `; this.container = this.shadowRoot('#container'); } attributeChangedCallback(attr, oldVal, newVal) { if(attr === 'disabled') { if(this.disabled) { this.container.classList.add('disabled'); } else { this.container.classList.remove('disabled') } } }}