前言
Custom Elements API 使我们可以定义自己的 HTML 标签及其行为。因此,我们可以通过使用自定义元素来创建我们自己的组件,这将使我们更轻松地将其用于项目中。使用自定义元素技术,我们需要解决多个组件通讯的问题。本文将讨论 Custom Elements 中子组件与父组件之间的通讯。
父组件向子组件传值
有时候,我们需要将一些属性从父组件传递到子组件中。我们可以使用以下方法:
方法一:使用 HTML 属性
<custom-element attribute="value"></custom-element>
通过在 HTML 中定义自定义元素时设置属性,子元素将自动获得这些传入的属性值。我们可以使用以下方式在子组件中访问这些属性。
// javascriptcn.com 代码示例 class ChildElement extends HTMLElement { constructor() { super(); } connectedCallback() { console.log(this.getAttribute('attribute')); } } window.customElements.define('child-element', ChildElement);
方法二:使用自定义元素的属性
<custom-element attribute="value"> <child-element attribute="value"></child-element> </custom-element>
在这里,子元素可以通过自定义元素的 properties 属性使用传递的参数。
// javascriptcn.com 代码示例 class ChildElement extends HTMLElement { constructor() { super(); } static get observedAttributes() { return ['attribute']; } connectedCallback() { console.log(this.getAttribute('attribute')); } attributeChangedCallback(name, oldValue, newValue) { console.log(`${name} changed from ${oldValue} to ${newValue}`); } } window.customElements.define('child-element', ChildElement);
子组件向父组件传值
有时候我们需要将从子组件中得到的值发送到父组件。为此, 我们可以使用以下方法:
方法一:通过 DOM 事件
我们可以通过在子元素上分发自定义的 DOM 事件来实现这个目标,然后在其父元素上侦听此事件。
// javascriptcn.com 代码示例 class ChildElement extends HTMLElement { constructor() { super(); this.counter = 0; } connectedCallback() { this.addEventListener('increment', () => { this.counter += 1; this.dispatchEvent(new CustomEvent('counter-updated', { detail: this.counter })); }); } } window.customElements.define('child-element', ChildElement);
在父元素中,我们需要添加事件监听器,以便他们可以使用 child-element 元素发送的事件接收倒计时。
// javascriptcn.com 代码示例 class ParentElement extends HTMLElement { constructor() { super(); this.attachShadow({ mode: 'open' }); this.shadowRoot.innerHTML = ` <h1>Hello World!</h1> <child-element></child-element> <p>Counter: <span id="counter"></span></p> `; } connectedCallback() { const childElement = this.shadowRoot.querySelector('child-element'); this.shadowRoot.getElementById('counter').textContent = childElement.counter; childElement.addEventListener('counter-updated', event => { this.shadowRoot.getElementById('counter').textContent = event.detail; }); } } window.customElements.define('parent-element', ParentElement);
这里, increment
事件在子元素中被触发,并且在此事件监听器内部, counter-updated
事件被创建,并带有更新后口令长度的 detail
参数。 counter-updated
事件将在父级元素中侦听。
方法二:直接使用父元素的方法
由于自定义元素的一个重要特性是它们可以包装现有的 HTML 元素,并为其添加新的行为和属性,因此,我们可以通过拓展祖先元素的生成对象来实现。
// javascriptcn.com 代码示例 class ChildElement extends HTMLElement { constructor() { super(); this.addEventListener('click', () => { this.upValue(); }); } connectedCallback() { this.counter = 0; } upValue() { this.counter = this.counter + 1; this.parentNode.upValue(); } } window.customElements.define('child-element', ChildElement);
在这种情况下,子组件直接访问给它一个函数以触发父元素中的逻辑。
// javascriptcn.com 代码示例 class ParentElement extends HTMLElement { constructor() { super(); this.attachShadow({ mode: 'open' }); this.shadowRoot.innerHTML = ` <h1>Hello World!</h1> <child-element></child-element> <p>Counter: <span id="counter"></span></p> `; } connectedCallback() { this.counter = 0; } upValue() { this.counter = this.counter + 1; this.shadowRoot.getElementById('counter').textContent = this.counter; } } window.customElements.define('parent-element', ParentElement);
在这里,子元素触发 upValue()
方法,从而触发祖先元素中的逻辑。
总结
本文介绍了父子组件通讯的多种方法,包括了以下两种情况:
- 父级元素向下级元素传递数据
- 子元素向父级元素传递数据
对于需要添加更高度自定义可复用性的组件,自定义元素技术是非常实用的。在考虑将组件引入项目中时,了解组件之间如何通信,以确保代码更健壮。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/654c7f877d4982a6eb5fb4b3