拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Quasar 框架 QTabPanels 与 QTabPanel 组件完全指南:多面板切换、滑动导航与无障碍实践

Quasar 框架 QTabPanels 与 QTabPanel 组件完全指南多面板切换、滑动导航与无障碍实践【免费下载链接】quasarQuasar Framework - Build high-performance VueJS user interfaces in record time项目地址: https://gitcode.com/gh_mirrors/qu/quasar导读QTabPanels / QTabPanel 是 Quasar FrameworkVue 组件库中用于用更少的窗口空间展示更多信息的核心面板组件通过v-model绑定当前激活面板支持动画过渡、触摸滑动、无限循环、keep-alive 缓存与深色模式。本指南以官方文档 tab-panels.md 为主线结合 QTabPanels.js、QTabPanel.js 与底层 use-panel.js 源码及测试用例带你掌握组件的全部配置项、与 QTabs 的组合模式、自定义过渡、滑动交互以及从 v2.25 起提供的 ARIA 无障碍实践。[!TIP] 本文聚焦 QTabPanels 组件本身。它常与 QTabsQTabs.js配合使用但并非必须——这一点在源码与文档中都被反复强调。一、组件定位两个组件各司其职QTabPanels 家族由两个组件组成组件角色源码位置QTabPanels容器面板宿主管理激活状态、动画、滑动、keep-aliveQTabPanels.jsQTabPanel单个面板内容单元声明name与可选disableQTabPanel.js从源码看QTabPanels的实现非常精简——它把全部行为逻辑抽取到了可复用的组合式函数usePanel中use-panel.js。同一套usePanel也被用于 QStepper 与 QCarousel 的面板部分因此你在学习本文内容时掌握的 props 与行为很大程度可以迁移到这两个组件上。// QTabPanels.js 核心结构节选 props: { ...usePanelProps, // modelValue / animated / swipeable / infinite / keepAlive 等 ...useDarkProps // dark }, emits: usePanelEmits // update:modelValue / beforeTransition / transitionQTabPanel则只是一个纯粹的展示单元渲染为一个div并将默认插槽内容放入其中h(div, { class: q-tab-panel, role: tabpanel, tabindex: 0 }, hSlot(slots.default))核心结论来自文档警告不要被 QTabPanels 的名字误导——面板不依赖 QTabs完全可以独立使用也可以放在页面任意位置不一定要紧挨着 QTabs。二、基础用法独立使用 QTabPanels即使没有 QTabs你也可以通过任意方式来切换面板例如用q-option-group或按钮绑定同一个v-model。以下是最简单的独立用法对应示例 Basic.vuetemplate div classq-pa-md div classq-gutter-y-md stylemax-width: 350px q-option-group v-modelpanel inline :options[ { label: Mails, value: mails }, { label: Alarms, value: alarms }, { label: Movies, value: movies } ] / q-tab-panels v-modelpanel animated classshadow-2 rounded-borders q-tab-panel namemails div classtext-h6Mails/div Lorem ipsum dolor sit amet consectetur adipisicing elit. /q-tab-panel q-tab-panel namealarms div classtext-h6Alarms/div Lorem ipsum dolor sit amet consectetur adipisicing elit. /q-tab-panel q-tab-panel namemovies div classtext-h6Movies/div Lorem ipsum dolor sit amet consectetur adipisicing elit. /q-tab-panel /q-tab-panels /div /div /template script setup import { ref } from vue const panel ref(mails) /script要点说明v-model即modelValue为必填 prop用于指定当前激活面板的name。从 use-panel.js 看modelValue被声明为required: true且通过getContentKey()兼容字符串与数字类型的name。每个QTabPanel的name是必需的且不能为空字符串、null或undefinedisValidPanelName()校验逻辑。渲染时未激活面板的内容默认不会渲染仅在keep-alive开启时保留缓存实例。三、与 QTabs 组合使用3.1 经典组合文档明确指出Works great along with QTabs, a component which offers a nice way to select the active tab panel to display. 两者通过共享同一个v-model值即name建立联系。完整示例见 WithQTabs.vuetemplate div classq-pa-md div classq-gutter-y-md stylemax-width: 600px q-card q-tabs v-modeltab dense classtext-grey active-colorprimary indicator-colorprimary alignjustify narrow-indicator q-tab namemails labelMails / q-tab namealarms labelAlarms / q-tab namemovies labelMovies / /q-tabs q-separator / q-tab-panels v-modeltab animated q-tab-panel namemails div classtext-h6Mails/div ... /q-tab-panel q-tab-panel namealarms div classtext-h6Alarms/div ... /q-tab-panel q-tab-panel namemovies div classtext-h6Movies/div ... /q-tab-panel /q-tab-panels /q-card /div /div /template script setup import { ref } from vue const tab ref(mails) /scriptWithQTabs.vue中还演示了第二个卡片面板可以放在 QTabs 的上方先 panels 后 tabs进一步印证了二者相对位置完全自由。3.2 嵌套 QTabs对于更复杂的布局官方提供了嵌套示例 WithNestedQTabs.vue即在一个外层QTabPanel内部再放一组QTabPanels QTabs形成多级选项卡结构。实现时只需保证内层使用独立的v-model变量即可。3.3 与垂直 QTabs、QSplitter 组合文档提供了一个经典侧边栏 内容区布局QSplitter左侧放垂直QTabs右侧放QTabPanels并设置vertical让滑动方向与过渡变为垂直。完整代码见 TabsAndSplitter.vue核心片段q-splitter v-modelsplitterModel styleheight: 250px template #before q-tabs v-modeltab vertical classtext-teal q-tab namemails iconmail labelMails / q-tab namealarms iconalarm labelAlarms / q-tab namemovies iconmovie labelMovies / /q-tabs /template template #after q-tab-panels v-modeltab animated swipeable vertical transition-prevjump-up transition-nextjump-up q-tab-panel namemails.../q-tab-panel q-tab-panel namealarms.../q-tab-panel q-tab-panel namemovies.../q-tab-panel /q-tab-panels /template /q-splitter四、Props 与事件完整速查基于源码以下是usePanelPropsuse-panel.js定义的全部配置项即 QTabPanels 支持的全部核心 propsProp类型默认值说明modelValueAny必填—当前激活面板的name支持字符串与数字animatedBooleanfalse是否在切换面板时播放过渡动画infiniteBooleanfalse到达首/末面板后是否循环配合swipeable或方法调用swipeableBooleanfalse是否允许鼠标/触摸滑动切换面板verticalBooleanfalse面板是否为垂直方向影响滑动方向与默认过渡transition-prevString见下文切换到上一个面板时使用的过渡名称transition-nextString见下文切换到下一个面板时使用的过渡名称transition-durationString/Number300过渡时长毫秒通过 CSS 变量--q-transition-duration注入keep-aliveBooleanfalse是否缓存已渲染面板的组件实例keep-alive-includeString/Array/RegExp—限定哪些面板进入缓存与 Vue KeepAlive 一致keep-alive-excludeString/Array/RegExp—限定哪些面板不缓存keep-alive-maxNumber—最大缓存实例数量darkBoolean—是否启用深色模式样式q-tab-panels--dark q-dark[!NOTE] 除了以上 propsQTabPanel自身还有name必填与disableBoolean禁用该面板禁用面板在切换与滑动时会被跳过。默认过渡规则来自源码getTransitionPrev/getTransitionNext水平模式上一个 →slide-right下一个 →slide-left垂直模式vertical上一个 →slide-down下一个 →slide-up在 RTL从右到左语言环境下水平模式的默认过渡方向会镜像反转$q.lang.rtl判断。事件emitsupdate:modelValue— 请求切换面板时触发beforeTransition— 过渡开始前触发(newVal, oldVal)transition— 过渡结束后触发延时transitionDuration毫秒。实例方法由usePanel通过Object.assign(proxy, ...)暴露next()— 切换到下一个已启用面板previous()— 切换到上一个已启用面板goTo(name)— 跳转到指定name的面板。这些方法可由模板 ref 调用例如this.$refs.panels.next()。五、着色Coloring用 Quasar 工具类快速定制外观面板本质是普通 DOM 容器因此可以自由使用 Quasar 的辅助类背景色、文字色、阴影、圆角等进行着色。官方示例 Coloring.vue 展示了三种风格卡片风格q-tab-panels上加classbg-primary text-white配合上方的 QTabs 使用active-color/indicator-color统一配色整体着色classbg-purple text-white让整个面板区域统一着色逐面板着色对单个q-tab-panel添加类如classbg-grey-9 text-white、classbg-lime-1 text-dark——注意QTabPanel的class属性会透传到其渲染出的div上。同时通过darkprop 或在$q.dark激活时面板会自动添加q-tab-panels--dark q-dark类以适配深色主题见 QTabPanels.js 中useDark的处理。六、自定义过渡Custom transitions启用animated后默认使用滑动过渡你可以通过transition-prev与transition-next替换为 Quasar 提供的任意过渡名称完整列表见 Transitions。官方示例 Transition.vue 演示了三种自定义组合!-- 缩放过渡 -- q-tab-panels v-modeltab animated transition-prevscale transition-nextscale classbg-purple text-white text-center ... /q-tab-panels !-- 淡入淡出过渡 -- q-tab-panels v-modeltab animated transition-prevfade transition-nextfade classbg-orange text-white text-center ... /q-tab-panels !-- 跳跃过渡prev 与 next 可不同 -- q-tab-panels v-modeltab animated transition-prevjump-up transition-nextjump-down classbg-teal text-white text-center ... /q-tab-panels源码层面的实现在 use-panel.js 中面板切换时通过updatePanelTransition(direction)计算q-transition--name类并用 Vue 的Transition组件包裹面板内容transitionDuration则通过内联样式--q-transition-duration: ${props.transitionDuration}ms注入到面板容器Quasar 的过渡 CSS 会消费这个变量。也就是说过渡仅在你同时传入animated且发生面板切换时才会启用。七、滑动与无限循环Swipeable infinite7.1 水平滑动在示例 Swipeable.vue 中同时开启animated、swipeable、infiniteq-tab-panels v-modelpanel animated swipeable infinite classbg-purple text-white shadow-2 rounded-borders ... /q-tab-panelsswipeable允许用户用鼠标拖拽mouse: true或在触摸设备上手指滑动来切换面板infinite在第一个面板向左滑或最后一个面板向右滑时直接循环到另一端不会停在边界。底层实现usePanel通过panelDirectives计算属性动态挂载TouchSwipe指令TouchSwipe.js。onSwipe根据vertical判断滑动手势方向水平为left垂直为up并结合 RTL 语言环境取反方向然后调用goToPanelByOffset(±1)。该方法会跳过disable的面板并在到达边界时根据infinite决定是否循环。值得注意的细节TouchSwipe只有在值value为函数时才采集手势源码注释提到这是为了避免在切换swipeable时因重新挂载指令而重建所有面板issue #12668。[!TIP] 文档提示如果面板内容中包含图片并且你想用滑动操作导航建议给这些图片加上draggablefalse否则浏览器的原生拖拽行为可能会干扰滑动手势。7.2 垂直滑动在 VerticalSwipeable.vue 中只需额外加上vertical即可让滑动方向与默认过渡变为上下方向常用于上下滑动的故事/卡片流场景q-tab-panels v-modelpanel animated swipeable vertical infinite classbg-purple text-white shadow-2 rounded-borders ... /q-tab-panels八、Keep-alive 缓存正确姿势与常见陷阱8.1 为什么需要 keep-alive默认情况下切走的面板会被销毁、切回时重新创建面板内部的组件状态如表单输入、滚动位置、计数器会丢失。QTabPanels提供了布尔 propkeep-alive启用后由组件内部对面板内容应用 Vue 的KeepAlive组件进行实例缓存。q-tab-panels v-modeltab keep-alive q-tab-panel namemails.../q-tab-panel /q-tab-panels测试用例QTabPanels.test.js验证了该行为挂载带keepAlive: true的面板 → 点击计数器 → 切到 panel-b → 切回 panel-a计数器的值仍为1证明实例被正确缓存。8.2 官方警告不要使用 Vue 原生keep-alive包裹 QTabPanel[!CAUTION]请务必使用 QTabPanels 的keep-aliveprop。不要用 Vue 原生的keep-alive组件去包裹QTabPanel。如果还需要keep-alive-include或keep-alive-exclude则 QTabPanel 的name必须是合法的 Vue 组件名不能包含空格、不能以数字开头。8.3 include/exclude 的源码级细节keepAliveInclude/keepAliveExclude/keepAliveMax会被收集为keepAliveProps直接传给 Vue 的KeepAlive。这里有一个微妙实现当使用include/exclude时KeepAlive的匹配目标是组件名因此usePanel会通过useRenderCache为每个面板生成一个带唯一name的包装组件needsUniqueKeepAliveWrapper判断确保include/exclude能按面板name精确匹配——这也是文档要求name必须符合组件命名规范的根本原因。所以请记住name使用简洁的 kebab-case 或 camelCase 标识符例如mails、alarms、settings-tab不要使用my tab含空格或123abc数字开头这类命名。九、无障碍AccessibilityARIA 角色与键盘可达性v2.25从 v2.25 起QTabPanel 在无障碍方面有了正式改进。其源码QTabPanel.js明确写了h(div, { class: q-tab-panel, role: tabpanel, // per the WAI-ARIA tabs pattern, so that keyboard users can // reach the panel content even when nothing in it is focusable tabindex: 0 }, ...)即每个 QTabPanel 都会渲染roletabpanelARIA 角色自带tabindex0即使面板内部没有任何可聚焦元素键盘与屏幕阅读器用户也能将焦点移入面板内容。对应的测试QTabPanel.test.js断言了roletabpanel与tabindex0的渲染并验证 ARIA 属性可以被覆盖与扩展例如传入tabindex-1或aria-labelledby。实践建议如果面板以自身的可聚焦内容开头如表单输入框为了避免多余的 Tab 停靠点可以给面板加tabindex-1由于 QTabPanels 不强制要求 QTabs两者可以放在页面任意位置组件无法自动为你建立tab 与 panel之间的 ARIA 关联。当你将它们配对使用时需要手动补齐aria-controls/aria-labelledby/idq-tabs v-modeltab q-tab namemails idmails-tab aria-controlsmails-panel labelMails / /q-tabs q-tab-panels v-modeltab q-tab-panel namemails idmails-panel aria-labelledbymails-tab ... /q-tab-panel /q-tab-panels这样屏幕阅读器用户就能在 tab 与 panel 之间获得完整的语义关联WAI-ARIA tabs pattern。十、综合实战清单与常见问题10.1 快速决策表需求配置纯内容切换无动画v-model即可平滑过渡加animated可配transition-prev/next手势滑动加swipeable首尾循环加infinite上下滑动/垂直布局加vertical保留面板状态加keep-alive配合 include/exclude/max跳过某些面板对应QTabPanel加disable深色主题加dark或依赖$q.dark无 QTabs 独立使用完全支持用任意控件绑定同一个v-model10.2 常见误区误以为必须搭配 QTabs不是。QTabPanels 是独立的容器组件用 Vue 原生keep-alive包 QTabPanel应使用组件的keep-alivepropname命名不规范需要keep-alive-include/exclude时name必须是合法组件名滑动时图片干扰给面板内图片加draggablefalse忘记animatedtransition-prev/next、transition-duration只有在animated开启时才会生效见updatePanelTransition源码逻辑。10.3 深入学习入口组件文档tab-panels.md组件实现QTabPanels.js、QTabPanel.js核心逻辑可复用于 QStepper/QCarousel 面板use-panel.js完整可运行示例QTabPanels 示例目录Basic、WithQTabs、WithNestedQTabs、Coloring、TabsAndSplitter、Transition、Swipeable、VerticalSwipeable测试用例QTabPanels.test.js、QTabPanel.test.js、use-panel.test.js相关组件QTabs 文档 tabs.md至此你已经掌握了 QTabPanels 从基础用法到源码级原理的全部关键点独立或配对使用、全套 props 与事件、着色定制、过渡与滑动交互、keep-alive 缓存以及 v2.25 的无障碍规范。下一步就可以在自己的 Quasar 应用中用更少的空间呈现更多信息了。【免费下载链接】quasarQuasar Framework - Build high-performance VueJS user interfaces in record time项目地址: https://gitcode.com/gh_mirrors/qu/quasar创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门