gpt4 book ai didi

javascript - 监听 child 或 parent 的事件以对 sibling 的变化使用react

转载 作者:行者123 更新时间:2023-11-28 03:30:01 24 4
gpt4 key购买 nike

我以原生 JS Web 组件格式创建了这个非常常见的菜单链接场景。

<side-nav>
<nav-item id="1">1</nav-item>
<nav-item id="2">2</nav-item>
<nav-item id="3">3</nav-item>
<nav-item id="4">4</nav-item>
</side-nav>

当然,当我点击任何导航项时,我需要

  • 使单击的项目处于事件/选中状态
  • 检查是否有另一个项目已处于事件状态,如果有,则使该导航项目处于非事件状态

通过网络组件,我发现我可以通过两种方式处理这个问题。

方法一:

jsfiddle

  • <nav-item> 时调度事件被点击
  • 在父节点上添加事件监听器 <side-nav>
  • 在每个点击事件上,循环遍历所有子项 <nav-item>侧面导航组件并停用已激活的 <nav-item>如果不是event.target节点。

代码<nav-item>

async connectedCallback() {
this.addEventListener('click' , (event) => {

this.setAttribute('selected', true);// immediately mark current component selected

this.dispatchEvent(new CustomEvent('navitem-selected', { bubbles: true, composed: true , detail: { id: this.id} })); // dispatch event, so that parent can loop and deselect other items
});
}

以及父代的代码 <side-nav>

async connectedCallback() {

this.addEventListener('navitem-selected', (event) => {
let items = this.shadowRoot.querySelector('slot').assignedElements();
items.forEach((item) => {
if(item.getAttribute('id') !== event.detail.id) {
item.removeAttribute('selected');
}
});
});
}

方法2:

jsfiddle

完全忽略父级并仅在 <nav-item> 中处理激活逻辑

static get observedAttributes() {
return ['id', 'selected'];
}

attributeChangedCallback(name, oldValue, newValue) {
if(name == 'id'){
this.id = newValue;
}
if(name == 'selected')
{
if(newValue){
this.shadowRoot.querySelector('.root').classList.add('selected');
} else {
this.shadowRoot.querySelector('.root').classList.remove('selected');
}
}
}


async connectedCallback() {
this.addEventListener('click' , (event) => {
this.dispatchEvent(new CustomEvent('navitem-selected', { bubbles: true, composed: true , detail: { id: this.id} }));
});
const hostNode = this.shadowRoot.querySelector('.root').getRootNode().host.parentNode;

hostNode.addEventListener('navitem-selected', (event) => {
if(this.id == event.detail.id){
this.setAttribute('selected', true);
} else if(this.hasAttribute('selected')){

this.removeAttribute('selected');
}
});
}

这两种方法都工作得很好,但就我而言,在考虑良好的编程实践和性能时,我无法弄清楚哪一种更好。

我有一个普遍的观念, child 不应该了解 sibling 或 parent ,但 parent 应该管理 child 。我对这里的最佳实践有点模糊,很乐意了解。

最佳答案

将其视为一组标准组件。大多数标准组件不了解任何其他组件。因此,父组件的工作是监听子组件的事件并根据需要对所有子组件进行更改。

唯一奇怪的组件是 <label>组件具有 for属性。您设置for属性为id单击 <label> 时将获得焦点的组件的名称。具有 click 的标签事件处理程序,如果有 for它会查找具有 id 属性的组件。如果它找到该组件,那么它会调用 .focus()该组件上的函数。

这样做时,您的组件不会捆绑在一起,而是可以连接在一起。

如果我编写代码,我会采用第一种方式。

关于javascript - 监听 child 或 parent 的事件以对 sibling 的变化使用react,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58263217/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com