Skip to content

Commit

Permalink
feat: tabbar support max count limit (#5490)
Browse files Browse the repository at this point in the history
* 标签栏支持限制打开的最大数量
  • Loading branch information
mynetfan authored Feb 6, 2025
1 parent a9f9031 commit 5262233
Show file tree
Hide file tree
Showing 11 changed files with 65 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ exports[`defaultPreferences immutability test > should not modify the config obj
"enable": true,
"height": 38,
"keepAlive": true,
"maxCount": 0,
"middleClickToClose": false,
"persist": true,
"showIcon": true,
Expand Down
1 change: 1 addition & 0 deletions packages/@core/preferences/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ const defaultPreferences: Preferences = {
enable: true,
height: 38,
keepAlive: true,
maxCount: 0,
middleClickToClose: false,
persist: true,
showIcon: true,
Expand Down
2 changes: 2 additions & 0 deletions packages/@core/preferences/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@ interface TabbarPreferences {
height: number;
/** 开启标签页缓存功能 */
keepAlive: boolean;
/** 限制最大数量 */
maxCount: number;
/** 是否点击中键时关闭标签 */
middleClickToClose: boolean;
/** 是否持久化标签 */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { computed } from 'vue';
import { $t } from '@vben/locales';
import NumberFieldItem from '../number-field-item.vue';
import SelectItem from '../select-item.vue';
import SwitchItem from '../switch-item.vue';
Expand All @@ -22,6 +23,7 @@ const tabbarWheelable = defineModel<boolean>('tabbarWheelable');
const tabbarStyleType = defineModel<string>('tabbarStyleType');
const tabbarShowMore = defineModel<boolean>('tabbarShowMore');
const tabbarShowMaximize = defineModel<boolean>('tabbarShowMaximize');
const tabbarMaxCount = defineModel<number>('tabbarMaxCount');
const tabbarMiddleClickToClose = defineModel<boolean>(
'tabbarMiddleClickToClose',
);
Expand Down Expand Up @@ -54,6 +56,16 @@ const styleItems = computed((): SelectOption[] => [
<SwitchItem v-model="tabbarPersist" :disabled="!tabbarEnable">
{{ $t('preferences.tabbar.persist') }}
</SwitchItem>
<NumberFieldItem
v-model="tabbarMaxCount"
:disabled="!tabbarEnable"
:max="30"
:min="0"
:step="5"
:tip="$t('preferences.tabbar.maxCountTip')"
>
{{ $t('preferences.tabbar.maxCount') }}
</NumberFieldItem>
<SwitchItem v-model="tabbarDraggable" :disabled="!tabbarEnable">
{{ $t('preferences.tabbar.draggable') }}
</SwitchItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,12 @@ withDefaults(
disabled?: boolean;
items?: SelectOption[];
placeholder?: string;
tip?: string;
}>(),
{
disabled: false,
placeholder: '',
tip: '',
items: () => [],
},
);
Expand All @@ -47,11 +49,17 @@ const slots = useSlots();
<span class="flex items-center text-sm">
<slot></slot>

<VbenTooltip v-if="slots.tip" side="bottom">
<VbenTooltip v-if="slots.tip || tip" side="bottom">
<template #trigger>
<CircleHelp class="ml-1 size-3 cursor-help" />
</template>
<slot name="tip"></slot>
<slot name="tip">
<template v-if="tip">
<p v-for="(line, index) in tip.split('\n')" :key="index">
{{ line }}
</p>
</template>
</slot>
</VbenTooltip>
</span>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ const tabbarPersist = defineModel<boolean>('tabbarPersist');
const tabbarDraggable = defineModel<boolean>('tabbarDraggable');
const tabbarWheelable = defineModel<boolean>('tabbarWheelable');
const tabbarStyleType = defineModel<string>('tabbarStyleType');
const tabbarMaxCount = defineModel<number>('tabbarMaxCount');
const tabbarMiddleClickToClose = defineModel<boolean>(
'tabbarMiddleClickToClose',
);
Expand Down Expand Up @@ -365,6 +366,7 @@ async function handleReset() {
v-model:tabbar-show-more="tabbarShowMore"
v-model:tabbar-style-type="tabbarStyleType"
v-model:tabbar-wheelable="tabbarWheelable"
v-model:tabbar-max-count="tabbarMaxCount"
v-model:tabbar-middle-click-to-close="tabbarMiddleClickToClose"
/>
</Block>
Expand Down
2 changes: 2 additions & 0 deletions packages/locales/src/langs/en-US/preferences.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@
"showMore": "Show More Button",
"showMaximize": "Show Maximize Button",
"persist": "Persist Tabs",
"maxCount": "Max Count of Tabs",
"maxCountTip": "When the number of tabs exceeds the maximum,\nthe oldest tab will be closed.\n Set to 0 to disable count checking.",
"draggable": "Enable Draggable Sort",
"wheelable": "Support Mouse Wheel",
"middleClickClose": "Close Tab when Mouse Middle Button Click",
Expand Down
2 changes: 2 additions & 0 deletions packages/locales/src/langs/zh-CN/preferences.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@
"showMore": "显示更多按钮",
"showMaximize": "显示最大化按钮",
"persist": "持久化标签页",
"maxCount": "最大标签数",
"maxCountTip": "每次打开新的标签时如果超过最大标签数,\n会自动关闭一个最先打开的标签\n设置为 0 则不限制",
"draggable": "启动拖拽排序",
"wheelable": "启用纵向滚轮响应",
"middleClickClose": "点击鼠标中键关闭标签页",
Expand Down
1 change: 1 addition & 0 deletions packages/stores/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
}
},
"dependencies": {
"@vben-core/preferences": "workspace:*",
"@vben-core/shared": "workspace:*",
"@vben-core/typings": "workspace:*",
"pinia": "catalog:",
Expand Down
10 changes: 9 additions & 1 deletion packages/stores/src/modules/tabbar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type { TabDefinition } from '@vben-core/typings';

import { toRaw } from 'vue';

import { preferences } from '@vben-core/preferences';
import {
openRouteInNewWindow,
startProgress,
Expand Down Expand Up @@ -107,6 +108,7 @@ export const useTabbarStore = defineStore('core-tabbar', {
});

if (tabIndex === -1) {
const maxCount = preferences.tabbar.maxCount;
// 获取动态路由打开数,超过 0 即代表需要控制打开数
const maxNumOfOpenTab = (routeTab?.meta?.maxNumOfOpenTab ??
-1) as number;
Expand All @@ -122,8 +124,14 @@ export const useTabbarStore = defineStore('core-tabbar', {
(item) => item.name === routeTab.name,
);
index !== -1 && this.tabs.splice(index, 1);
} else if (maxCount > 0 && this.tabs.length >= maxCount) {
// 关闭第一个
const index = this.tabs.findIndex(
(item) =>
!Reflect.has(item.meta, 'affixTab') || !item.meta.affixTab,
);
index !== -1 && this.tabs.splice(index, 1);
}

this.tabs.push(tab);
} else {
// 页面已经存在,不重复添加选项卡,只更新选项卡参数
Expand Down
23 changes: 23 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 5262233

Please # to comment.