更新记录

1.0.0(2026-11-02) 下载此版本

  • 初始版本。从 open_novel/content-management/windows/workTabBar.vue 解耦:
    • 移除 vuex / vue-router / remix-icon 依赖,改为数据驱动(items / activeKey 等 Props)。
    • 导航与标签状态管理全部以事件外抛(select / close / home / action)。
    • 菜单项的禁用态由组件依据 items / activeKey / 目标项纯逻辑计算。
    • 样式仅使用 uni 官方 $uni-* 令牌,无硬编码色值。
    • 首页 / 更多 / 关闭 / 菜单图标均提供具名插槽,默认用 Unicode 字形兜底。
    • 横向滚动承载层改为内部 inline-flex,规避 H5 下 scroll-view 块级包裹导致换行的问题。

平台兼容性

uni-app(3.8.12)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
- √ √ √ √ √ √ √ √
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
√ √ √ √ √ √ √ √ √ √ √ √

u-work-tab-bar

工作标签页栏(类浏览器多标签页)。从 open_novel/content-management/windows/workTabBar.vue 解耦而来:数据驱动 + 事件外抛,零业务依赖——不耦合 vuex / vue-router / remix-icon, 不内置任何跳转逻辑,导航与标签状态管理全部由消费方负责。

特性

  • 可横向滚动的已打开标签列表,激活标签自动滚动到可视区(scroll-into-view)。
  • 单个标签可关闭(非固定 + 多标签时显示关闭按钮)。
  • 标签支持「固定」:固定标签不可关闭,且不受「关闭其他 / 关闭全部」影响。
  • 首页按钮、更多按钮独立可配。
  • 右键标签 / 点击「更多」弹出操作菜单:刷新、固定、关闭左侧 / 右侧 / 其他 / 全部; 菜单项的禁用态由组件依据 items / activeKey / 目标项纯逻辑计算。
  • 样式仅用 uni 官方 $uni-* 令牌,无硬编码色值(样式抽离到 u-work-tab-bar.scss)。
  • 图标默认用 vant-icon(内置字体图标,apps-o / arrow-down / cross 等),与原始 workTabBar.vue 的 remix 语义一一对应;全部通过具名插槽可替换为任意图标(remix-icon / uni-icons 等)。
  • 类型契约抽离到 props.ts(WorkTabItem / WorkTabMenuKey / WorkTabMenuItem / WorkTabBarProps),与 vant-* 组件拆分约定一致。

文件结构

u-work-tab-bar/
├── components/u-work-tab-bar/
│   ├── u-work-tab-bar.vue      # 模板 + 逻辑(import 自 props.ts,样式 src 自 .scss)
│   ├── props.ts                # 对外类型契约
│   └── u-work-tab-bar.scss     # 全部样式(仅用 $uni-* 令牌)
├── package.json
├── readme.md
└── changelog.md

Props

属性 类型 默认值 说明
items WorkTabItem[] [] 已打开标签列表
activeKey string '' 当前激活标签的 key
showHome boolean true 是否展示首页按钮
showMore boolean true 是否展示更多按钮
homeTitle string '首页' 首页按钮文案 / aria
moreTitle string '更多' 更多按钮文案 / aria
menu WorkTabMenuKey[] ['refresh','pin','left','right','other','all'] 弹出菜单展示的操作项(可裁剪)
closableDefault boolean true 非固定标签是否默认显示关闭按钮

WorkTabItem:{ key: string; title: string; fixed?: boolean; closable?: boolean } WorkTabMenuKey:'refresh' | 'pin' | 'left' | 'right' | 'other' | 'all'

Events

事件 载荷 说明
select key: string 点击标签
close key: string 点击标签关闭按钮
home — 点击首页按钮
action { action: WorkTabMenuKey; key: string } 点击弹出菜单项(refresh/pin/left/right/other/all)

刷新 / 固定 / 关闭类操作均只抛出语义事件,由消费方对接 vuex mutation、路由跳转、 页面刷新等业务逻辑。组件本身不读写 store、不调用 uni.redirectTo。

Slots

插槽名 作用域 默认内容 说明
home — vant-icon apps-o 首页 / 仪表盘按钮图标
more — vant-icon arrow-down 更多按钮图标
close { item } vant-icon cross 单个标签关闭按钮图标
menu-icon { actionKey, label, disabled } vant-icon 按 action 映射 弹出菜单项图标:refresh→replay / pin→bookmark-o / left→arrow-left / right→arrow / other→cross / all→close

菜单定位

  • 两种模式统一为 absolute,定位父级都是 .u-work-tab-bar__more-wrap(position: relative)。
  • 「更多」菜单由 纯 CSS 锚定:top: calc(100% + 6px); right: 0 —— 恒在标签栏正下方、右缘与更多按钮对齐,零测量。
  • 右键菜单锚到被右键标签的正下方、右缘与该标签对齐:先用 getBoundingClientRect() 在视口坐标里算好位置(含防溢出与左右翻转), 再按锚点容器的视口矩形与缩放比(rect.width / offsetWidth)换算成局部坐标写入内联样式。 因此页面滚动、祖先 transform、预览缩放都不会让菜单漂移。
  • 防溢出规则:菜单底部超出视口时只上移到标签下沿为止,绝不高于标签栏(矮视口下宁可向下溢出), 避免“弹窗跑到标签上方”遮住标签栏与页面头部。
  • ⚠️ 菜单是绝对定位元素,祖先 overflow: hidden 会裁剪菜单。若标签栏放在带裁剪的容器(如圆角浮窗)里, 请让该容器 overflow: visible,或保证菜单的展开区域在容器内。
  • 菜单项图标与文字共用 18px 行盒,并对 vant-icon 字形墨迹的 1px 上偏做补偿,保证图标与文字视觉中心重合。

关闭按钮

  • 关闭按钮为 16×16 圆形(hover 显示浅底),padding 让图标与圆边留白,可按需调整。
  • 图标(默认 vant-icon cross)以 absolute + top/left 50% + translate(-50%, -50%) 落在圆心, 不受 padding、图标盒子尺寸与字体基线影响。
  • 默认 opacity: 0.6(vant-icon 自带行内 color,故用 opacity 收敛),hover 恢复满色。

用法示例

<template>
  <u-work-tab-bar
    :items="tabs"
    :active-key="activeKey"
    @select=""
    @close="onClose"
    @home="onHome"
    @action="onAction"
  >
    <!-- 可选:用 remix-icon / uni-icons 替换默认 vant-icon(不传插槽则显示内置 vant-icon) -->
    <template #home><remix-icon name="dashboard-line" :size="18" /></template>
    <template #more><remix-icon name="arrow-down-s-line" :size="20" /></template>
    <template #close><remix-icon name="close-large-fill" :size="10" /></template>
    <template #menu-icon="{ actionKey }">
      <remix-icon :name="menuIconMap[actionKey]" :size="15" />
    </template>
  </u-work-tab-bar>
</template>

<script setup lang="ts">
import { ref } from 'vue'

const tabs = ref([
  { key: '/', title: '工作台', fixed: true },
  { key: '/order/list', title: '订单列表' },
  { key: '/user/detail', title: '用户详情' },
])
const activeKey = ref('/order/list')

const menuIconMap: Record<string, string> = {
  refresh: 'refresh-line',
  pin: 'pushpin-2-line',
  left: 'arrow-left-s-line',
  right: 'arrow-right-s-line',
  other: 'close-fill',
  all: 'close-circle-line',
}

function (key: string) {
  // 业务:跳转 / 激活对应页
}
function onClose(key: string) {
  // 业务:从 store 移除该标签,必要时跳转到相邻标签
}
function onHome() {
  // 业务:回到首页
}
function onAction({ action, key }: { action: string; key: string }) {
  // 业务:刷新 / 固定 / 关闭左·右·其他·全部
}
</script>

隐私、权限声明

1. 本插件需要申请的系统权限列表:

无

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

无

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

无

许可协议

MIT协议

暂无用户评论。