最稳方式是用 javascript 控制 active 类而非 v-if 或 display: none;用 data-tab 与 id 关联按钮和面板更可靠;含表单/iframe 的面板须用 hidden 属性;需支持键盘导航并正确设置 aria 属性。

直接用 JavaScript 控制 active 类是最稳、最可控的方式,别碰 v-if 或 display: none 硬切——表单会丢值、iframe 会重载、动画会中断。
怎么用 data-tab 关联按钮和面板
靠属性绑定比靠 DOM 顺序更可靠,哪怕你把 HTML 顺序打乱、增删 tab,也不会错位。
- 每个按钮加
data-tab="user",对应面板的id也得是user - 面板不用写
data-tab-pane,用id就够了;JS 里用document.getElementById(tabValue)直接取,干净不绕弯 - 避免用
querySelectorAll('div:nth-child(2)')这类索引式定位,DOM 变动后立刻失效
为什么不能只改 display: none
display: none 会让内部资源彻底“断电”:iframe 停止加载、video 暂停、input 失去焦点且清空输入历史。这不是隐藏,是卸载。
- 轻量内容(纯文本、静态图)可以接受
display: none - 含表单、地图、播放器的面板,必须用
hidden属性 + CSS 规则[hidden] { display: none; } - 别在 JS 里写
el.style.display = 'none',它会覆盖外部样式,且无法和 transition 配合
键盘导航必须手动接管 focus
只绑 click 事件,键盘用户根本进不来。Tab 键进不到 tab 按钮,方向键切不了页签,这是无障碍硬伤。
- 所有按钮设
tabindex="0",非激活态动态设为tabindex="-1" - 监听
keydown,对ArrowLeft/ArrowRight找相邻有效按钮并调用.focus() - 按
Enter或Space时,触发button.click()复用已有逻辑,别重复写切换代码 - 切换完成后,把焦点移到对应
tabpanel(需加tabindex="-1"),否则焦点悬空
aria 属性不是可选项,是必填项
没有 role="tablist" 和 aria-selected,屏幕阅读器会把一排按钮读成“按钮、按钮、按钮”,完全不知道哪一个是当前页签。
- 外层容器加
role="tablist" - 每个按钮加
role="tab"、aria-controls="panel-id"、aria-selected="true/false" - 每个面板加
role="tabpanel"、aria-labelledby="tab-id"、初始带hidden属性 - 用 JS 切换时,同步更新
aria-selected和hidden,不能只动 class
最易被忽略的是:切换后没把焦点移到内容区,以及 hidden 属性和 aria-hidden 混用——hidden 已隐含语义,再加 aria-hidden="true" 反而干扰读屏器。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











