npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@cimom/vben-core-tabs-ui

v5.6.9

Published

Tabs UI 组件是一个基于 Vue 3 的标签页组件,提供了丰富的配置选项,支持拖拽排序、滚轮滚动、右键菜单等功能,适用于各种标签页导航场景。

Readme

Tabs UI 组件

Tabs UI 组件是一个基于 Vue 3 的标签页组件,提供了丰富的配置选项,支持拖拽排序、滚轮滚动、右键菜单等功能,适用于各种标签页导航场景。

安装

npm install @cimom/vben-core-ui-kit-tabs-ui

基本使用

<script setup lang="ts">
import { TabsView } from '@cimom/vben-core-ui-kit-tabs-ui';
import { ref } from 'vue';

const activeTab = ref('tab1');
const tabs = ref([
  { key: 'tab1', title: '标签页1', closable: true },
  { key: 'tab2', title: '标签页2', closable: true },
  { key: 'tab3', title: '标签页3', closable: true },
]);

const handleClose = (key: string) => {
  const index = tabs.value.findIndex((item) => item.key === key);
  if (index !== -1) {
    tabs.value.splice(index, 1);
    if (activeTab.value === key && tabs.value.length) {
      activeTab.value = tabs.value[index - 1 >= 0 ? index - 1 : 0].key;
    }
  }
};
</script>

<template>
  <div class="h-10">
    <TabsView v-model:active="activeTab" :tabs="tabs" @close="handleClose" />
  </div>

  <div class="p-4">
    <div v-if="activeTab === 'tab1'">标签页1的内容</div>
    <div v-if="activeTab === 'tab2'">标签页2的内容</div>
    <div v-if="activeTab === 'tab3'">标签页3的内容</div>
  </div>
</template>

组件属性

TabsView Props

| 属性名 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | | active | string | - | 当前激活的标签页 key | | tabs | TabDefinition[] | [] | 标签页数据 | | styleType | 'chrome' \| 'default' | 'chrome' | 标签页风格 | | draggable | boolean | true | 是否可以拖拽排序 | | wheelable | boolean | true | 是否响应滚轮事件 | | contentClass | string | 'vben-tabs-content' | 内容区域的类名 | | showIcon | boolean | - | 是否显示图标 | | middleClickToClose | boolean | - | 是否允许鼠标中键点击关闭标签页 | | contextMenus | (data: any) => IContextMenuItem[] | - | 右键菜单配置函数 | | gap | number | 7 | 标签页之间的间隙(仅 chrome 风格有效) | | minWidth | number | - | 标签页最小宽度(仅 chrome 风格有效) | | maxWidth | number | - | 标签页最大宽度(仅 chrome 风格有效) |

TabDefinition 标签页配置

| 属性名 | 类型 | 说明 | | -------- | --------- | ------------------------ | | key | string | 标签页唯一标识 | | title | string | 标签页标题 | | icon | string | 标签页图标 | | closable | boolean | 是否可关闭 | | affixTab | boolean | 是否固定标签(不可关闭) |

事件

| 事件名 | 参数 | 说明 | | --- | --- | --- | | update:active | (key: string) => void | 激活标签页变化时触发 | | close | (key: string) => void | 关闭标签页时触发 | | sortTabs | (oldIndex: number, newIndex: number) => void | 拖拽排序标签页时触发 | | unpin | (tab: TabDefinition) => void | 取消固定标签页时触发 |

标签页风格

Tabs UI 组件支持两种标签页风格:

  • 'chrome': Chrome 浏览器风格的标签页(默认)
  • 'default': 普通风格的标签页
<template>
  <TabsView v-model:active="activeTab" :tabs="tabs" styleType="chrome" />
</template>

拖拽排序

Tabs UI 组件默认支持拖拽排序功能,可以通过 draggable 属性控制是否启用:

<template>
  <TabsView
    v-model:active="activeTab"
    :tabs="tabs"
    :draggable="true"
    @sortTabs="handleSortTabs"
  />
</template>

<script setup>
const handleSortTabs = (oldIndex, newIndex) => {
  // 处理标签页排序逻辑
  const tab = tabs.value.splice(oldIndex, 1)[0];
  tabs.value.splice(newIndex, 0, tab);
};
</script>

右键菜单

Tabs UI 组件支持自定义右键菜单,可以通过 contextMenus 属性配置:

<template>
  <TabsView
    v-model:active="activeTab"
    :tabs="tabs"
    :contextMenus="getContextMenus"
  />
</template>

<script setup>
const getContextMenus = (tab) => {
  return [
    {
      label: '刷新',
      onClick: () => {
        console.log('刷新标签页:', tab);
      },
    },
    {
      label: '关闭',
      onClick: () => {
        handleClose(tab.key);
      },
      disabled: !tab.closable,
    },
    {
      label: '关闭其他',
      onClick: () => {
        tabs.value = tabs.value.filter(
          (item) => item.key === tab.key || !item.closable,
        );
      },
    },
    {
      label: '关闭所有',
      onClick: () => {
        tabs.value = tabs.value.filter((item) => !item.closable);
      },
    },
  ];
};
</script>

示例

带图标的标签页

<template>
  <div class="h-10">
    <TabsView
      v-model:active="activeTab"
      :tabs="tabs"
      :showIcon="true"
      @close="handleClose"
    />
  </div>

  <div class="p-4">
    <component :is="activeComponent" />
  </div>
</template>

<script setup lang="ts">
import { TabsView } from '@cimom/vben-core-ui-kit-tabs-ui';
import { computed, ref, shallowRef } from 'vue';
import DashboardView from './views/Dashboard.vue';
import UserView from './views/User.vue';
import SettingView from './views/Setting.vue';

const activeTab = ref('dashboard');
const tabs = ref([
  {
    key: 'dashboard',
    title: '仪表盘',
    icon: 'Dashboard',
    closable: false,
    affixTab: true,
  },
  {
    key: 'user',
    title: '用户管理',
    icon: 'User',
    closable: true,
  },
  {
    key: 'setting',
    title: '系统设置',
    icon: 'Setting',
    closable: true,
  },
]);

const componentMap = {
  dashboard: DashboardView,
  user: UserView,
  setting: SettingView,
};

const activeComponent = computed(() => {
  return componentMap[activeTab.value] || null;
});

const handleClose = (key: string) => {
  const index = tabs.value.findIndex((item) => item.key === key);
  if (index !== -1) {
    tabs.value.splice(index, 1);
    if (activeTab.value === key && tabs.value.length) {
      activeTab.value = tabs.value[index - 1 >= 0 ? index - 1 : 0].key;
    }
  }
};
</script>

动态添加标签页

<template>
  <div class="mb-4">
    <button
      class="mr-2 rounded bg-blue-500 px-4 py-2 text-white"
      @click="addTab"
    >
      添加标签页
    </button>
  </div>

  <div class="h-10">
    <TabsView
      v-model:active="activeTab"
      :tabs="tabs"
      styleType="chrome"
      @close="handleClose"
    />
  </div>

  <div class="mt-2 rounded border p-4">
    <div>当前激活的标签页: {{ activeTab }}</div>
    <div>标签页数量: {{ tabs.length }}</div>
  </div>
</template>

<script setup lang="ts">
import { TabsView } from '@cimom/vben-core-ui-kit-tabs-ui';
import { ref } from 'vue';

const activeTab = ref('tab1');
const tabs = ref([{ key: 'tab1', title: '标签页1', closable: true }]);

let tabIndex = 1;

const addTab = () => {
  tabIndex++;
  const newTab = {
    key: `tab${tabIndex}`,
    title: `标签页${tabIndex}`,
    closable: true,
  };
  tabs.value.push(newTab);
  activeTab.value = newTab.key;
};

const handleClose = (key: string) => {
  const index = tabs.value.findIndex((item) => item.key === key);
  if (index !== -1) {
    tabs.value.splice(index, 1);
    if (activeTab.value === key && tabs.value.length) {
      activeTab.value = tabs.value[index - 1 >= 0 ? index - 1 : 0].key;
    }
  }
};
</script>

固定标签页

<template>
  <div class="h-10">
    <TabsView
      v-model:active="activeTab"
      :tabs="tabs"
      styleType="chrome"
      @close="handleClose"
    />
  </div>
</template>

<script setup lang="ts">
import { TabsView } from '@cimom/vben-core-ui-kit-tabs-ui';
import { ref } from 'vue';

const activeTab = ref('home');
const tabs = ref([
  { key: 'home', title: '首页', closable: false, affixTab: true },
  { key: 'dashboard', title: '仪表盘', closable: false, affixTab: true },
  { key: 'user', title: '用户管理', closable: true },
  { key: 'role', title: '角色管理', closable: true },
]);

const handleClose = (key: string) => {
  const index = tabs.value.findIndex((item) => item.key === key);
  if (index !== -1) {
    tabs.value.splice(index, 1);
    if (activeTab.value === key && tabs.value.length) {
      activeTab.value = tabs.value[index - 1 >= 0 ? index - 1 : 0].key;
    }
  }
};
</script>