Ember版ivy-tabs默认标签页设置及标签切换异常问题求助
我明白你遇到的麻烦了——当给标签加上错误类名时,标签页会自动切换,这确实很影响体验。咱们来一步步解决这个问题:
问题根源分析
你现在用{{#unless}}/{{else}}分别渲染不同类名的tablist.tab组件,这会导致当errorTabs的状态变化时,原来的tab组件会被销毁,新的tab组件重新创建。而ivy-tabs在组件重新挂载时,可能会触发默认的选中逻辑,或者因为组件重建导致外部的selection状态和组件内部状态不同步,最终引发自动切换。
最优解决方案:动态绑定类名(避免组件重渲染)
不要通过条件渲染整个tab组件,而是直接动态绑定class属性,这样组件不会被销毁重建,只是类名发生变化,自然就不会触发自动切换了。修改后的模板代码如下:
{{#ivy-tabs selection=selection as |tabs|}} <div class="edit_profile"> <div class="modal--content--sidebar"> {{#tabs.tablist as |tablist| }} <ul role="presentation" class="modal_tabs"> <li role="presentation" class="modal_tabs--item ivy-tabs-tab"> {{#tablist.tab "TabA" class=(concat "modal_tabs--item_a ivy-tabs-tab" (if errorTabs.personal " edit_profile--tab_error")) on-select=(action (mut selection)) }} Personal {{/tablist.tab}} </li> <li role="presentation" class="modal_tabs--item ivy-tabs-tab"> {{#tablist.tab "TabB" class=(concat "modal_tabs--item_a" (if errorTabs.contact " edit_profile--tab_error")) on-select=(action (mut selection)) }} Contact {{/tablist.tab}} </li> <li role="presentation" class="modal_tabs--item ivy-tabs-tab "> {{#tablist.tab "TabC" class=(concat "modal_tabs--item_a" (if errorTabs.professional " edit_profile--tab_error")) on-select=(action (mut selection)) }} Professional {{/tablist.tab}} </li> </ul> {{/tabs.tablist}} </div> <div class="modal--content--container"> <div class="modal--content--scroll_container"> {{#tabs.tabpanel "TabA" }} {{something here}} {{/tabs.tabpanel}} {{#tabs.tabpanel "TabB" }} {{something here}} {{/tabs.tabpanel}} {{#tabs.tabpanel "TabC" }} {{something here}} {{/tabs.tabpanel}} </div> </div> {{/ivy-tabs}}
这里用concat和if助手动态拼接类名:当errorTabs对应的属性为true时,自动添加上edit_profile--tab_error类,全程不需要销毁重建tab组件,完美避免自动切换的问题。
备选方案:手动控制selection状态
如果因为某些原因必须保留条件渲染的写法,可以在组件/控制器中手动维护selection状态,确保错误状态变化时不会自动切换标签。比如在组件的JavaScript文件中添加监听逻辑:
import Component from '@glimmer/component'; import { tracked } from '@glimmer/tracking'; import { action } from '@ember/object'; export default class EditProfileTabsComponent extends Component { @tracked selection = 'TabA'; // 设置默认选中的标签 @tracked errorTabs = { personal: false, contact: false, professional: false }; @action updateErrorTabs(newErrors) { this.errorTabs = newErrors; // 强制保持当前选中状态,或者重置为默认值 this.selection = this.selection || 'TabA'; } }
这样当errorTabs更新时,我们手动锁定selection的值,防止组件重渲染导致的自动切换。
额外优化:自定义点击事件控制切换
你还可以自定义on-select的action,只在用户主动点击标签时才允许切换,进一步避免意外的自动切换:
// 组件js中添加action @action handleTabSelect(tabName, event) { // 仅当事件来自用户点击时才更新选中状态 if (event?.type === 'click') { this.selection = tabName; } }
然后模板中修改on-select绑定:
{{#tablist.tab "TabA" class=(concat "modal_tabs--item_a ivy-tabs-tab" (if errorTabs.personal " edit_profile--tab_error")) on-select=(action "handleTabSelect") }} Personal {{/tablist.tab}}
这样就能确保只有用户主动点击标签时才会切换,完全杜绝自动切换的情况。
内容的提问来源于stack exchange,提问作者Thilina Dinith Fonseka

