如何解决模具组件未呈现更新的选项卡
import { Component,h,State } from '@stencil/core';
// import '@webcomponents/custom-elements';
import '@clr/core/icon/register';
import { ClarityIcons,plusIcon } from '@clr/core/icon';
ClarityIcons.addIcons(plusIcon);
@Component({
tag: 'tabs-component',styleUrl: 'tabs-component.css',shadow: false,})
export class TabsComponent {
@State() tabs: Array<object> = [
(
<li role="presentation" class="nav-item">
<button id="tab3" class="btn btn-link nav-link" aria-controls="panel3"
aria-selected="false" type="button">Cloud</button>
</li>
)
];
addTab(onHead = true) {
// debugger
const tab = (
<li role="presentation" class="nav-item">
<button id="tab3" class="btn btn-link nav-link" aria-controls="panel3"
aria-selected="false" type="button">Dashboard</button>
</li>
);
if (onHead) {
this.tabs.unshift(tab);
} else {
this.tabs.push(tab);
}
console.log(this.tabs);
}
render() {
return (
<div>
<ul id="demoTabs" class="nav" role="tablist">
<li role="presentation" class="nav-item" onClick={() => this.addTab()}>
<cds-icon shape="plus" class="cursor"></cds-icon>
</li>
{this.tabs}
</ul>
<section id="panel1" role="tabpanel" aria-labelledby="tab1">
tab1
</section>
<section id="panel2" role="tabpanel" aria-labelledby="tab2" aria-hidden="true">
tab2
</section>
<section id="panel3" role="tabpanel" aria-labelledby="tab3" aria-hidden="true">
tab3
</section>
</div>
);
}
}
解决方法
模具执行严格的相等性检查(===
),以确定Prop / State变量是否已更改,这就是为什么它未将push
和unshift
检测为更改的原因。您必须确保用新阵列替换该阵列。在您的示例中,执行此操作最快的方法是在操作后用副本手动替换阵列:
if (onHead) {
this.tabs.unshift(tab);
} else {
this.tabs.push(tab);
}
this.tabs = [...this.tabs];
请参见the Stencil docs for updating arrays。
,这是参照相等性的问题。对象始终按引用传递而不是按值传递,因此,两个对象永远不会相等(就引用而言,即使它们包含相同的值)也是如此。
数组是一种特殊的对象,因此也通过引用传递。修改数组的值不会更改其引用。
一些例子来说明这一点:
const foo = ['a','b'];
console.log(foo === ['a','b','c']); // false
foo.push('c');
console.log(foo === ['a','c']); // still false
console.log(['a','c'] === ['a','c']); // actually always false
console.log(foo === foo); // always true because it is the same reference
模板使用相同的严格相等运算符@State()
比较===
装饰的类成员(@Prop()
也是如此)。如果值相同,则不重新渲染组件。
对于tabs
状态,this.tabs
的值是对您为其分配的数组的引用。修改数组(例如this.tabs.push(...)
)只会更改this.tabs
所引用的数组的值,而不会更改存储在this.tabs
中的实际引用。
因此,您需要重新分配this.tabs
,以使Stencil知道此成员已更改。最简单的方法是
this.tabs = [...this.tabs];
将数组的值散布到一个新的数组中(返回一个新的引用)。另外,诸如this.tabs = this.tabs.slice()
之类的方法也可以解决问题(任何返回新数组的方法都可以使用)。
对于您来说,最简单的方法是将addTab
方法更改为
addTab(onHead = true) {
const tab = (
<li role="presentation" class="nav-item">
<button id="tab3" class="btn btn-link nav-link" aria-controls="panel3"
aria-selected="false" type="button">Dashboard</button>
</li>
);
this.tabs = onHead ? [tab,...this.tabs] : [...this.tabs,tab];
}
(即在新项目之前或之后散布原始值)。
,看起来像temp变量起作用了,很奇怪。
const tempTabs = [...this.tabs];
if (onHead) {
tempTabs.unshift(tab);
} else {
tempTabs.push(tab);
}
this.tabs = tempTabs;
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。