5.6.9 • Published 4 months ago
@cimom/vben-core-tabs-ui v5.6.9
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>