Merge branch 'main' of https://github.com/vbenjs/vue-vben-admin into dev
This commit is contained in:
commit
551841bdd7
@ -347,7 +347,7 @@ export interface ActionButtonOptions {
|
||||
/** 是否显示 */
|
||||
show?: boolean;
|
||||
/** 按钮文本 */
|
||||
text?: string;
|
||||
content?: string;
|
||||
/** 任意属性 */
|
||||
[key: string]: any;
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -80,6 +80,7 @@ const defaultPreferences: Preferences = {
|
||||
enable: true,
|
||||
height: 38,
|
||||
keepAlive: true,
|
||||
maxCount: 0,
|
||||
middleClickToClose: false,
|
||||
persist: true,
|
||||
showIcon: true,
|
||||
|
@ -168,6 +168,8 @@ interface TabbarPreferences {
|
||||
height: number;
|
||||
/** 开启标签页缓存功能 */
|
||||
keepAlive: boolean;
|
||||
/** 限制最大数量 */
|
||||
maxCount: number;
|
||||
/** 是否点击中键时关闭标签 */
|
||||
middleClickToClose: boolean;
|
||||
/** 是否持久化标签 */
|
||||
|
@ -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';
|
||||
|
||||
@ -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',
|
||||
);
|
||||
@ -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>
|
||||
|
@ -1,7 +1,10 @@
|
||||
<script setup lang="ts">
|
||||
import type { SelectOption } from '@vben/types';
|
||||
|
||||
import { useSlots } from 'vue';
|
||||
|
||||
import { CircleHelp } from '@vben/icons';
|
||||
|
||||
import {
|
||||
NumberField,
|
||||
NumberFieldContent,
|
||||
@ -10,7 +13,6 @@ import {
|
||||
NumberFieldInput,
|
||||
VbenTooltip,
|
||||
} from '@vben-core/shadcn-ui';
|
||||
import { useSlots } from 'vue';
|
||||
|
||||
defineOptions({
|
||||
name: 'PreferenceSelectItem',
|
||||
@ -21,10 +23,12 @@ withDefaults(
|
||||
disabled?: boolean;
|
||||
items?: SelectOption[];
|
||||
placeholder?: string;
|
||||
tip?: string;
|
||||
}>(),
|
||||
{
|
||||
disabled: false,
|
||||
placeholder: '',
|
||||
tip: '',
|
||||
items: () => [],
|
||||
},
|
||||
);
|
||||
@ -45,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>
|
||||
|
||||
|
@ -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',
|
||||
);
|
||||
@ -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>
|
||||
|
@ -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",
|
||||
|
@ -62,6 +62,8 @@
|
||||
"showMore": "显示更多按钮",
|
||||
"showMaximize": "显示最大化按钮",
|
||||
"persist": "持久化标签页",
|
||||
"maxCount": "最大标签数",
|
||||
"maxCountTip": "每次打开新的标签时如果超过最大标签数,\n会自动关闭一个最先打开的标签\n设置为 0 则不限制",
|
||||
"draggable": "启动拖拽排序",
|
||||
"wheelable": "启用纵向滚轮响应",
|
||||
"middleClickClose": "点击鼠标中键关闭标签页",
|
||||
|
@ -20,6 +20,7 @@
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@vben-core/preferences": "workspace:*",
|
||||
"@vben-core/shared": "workspace:*",
|
||||
"@vben-core/typings": "workspace:*",
|
||||
"pinia": "catalog:",
|
||||
|
@ -1,13 +1,17 @@
|
||||
import type { TabDefinition } from '@vben-core/typings';
|
||||
import type { Router, RouteRecordNormalized } from 'vue-router';
|
||||
|
||||
import type { TabDefinition } from '@vben-core/typings';
|
||||
|
||||
import { toRaw } from 'vue';
|
||||
|
||||
import { preferences } from '@vben-core/preferences';
|
||||
import {
|
||||
openRouteInNewWindow,
|
||||
startProgress,
|
||||
stopProgress,
|
||||
} from '@vben-core/shared/utils';
|
||||
|
||||
import { acceptHMRUpdate, defineStore } from 'pinia';
|
||||
import { toRaw } from 'vue';
|
||||
|
||||
interface TabbarState {
|
||||
/**
|
||||
@ -104,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;
|
||||
@ -119,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 {
|
||||
// 页面已经存在,不重复添加选项卡,只更新选项卡参数
|
||||
|
Loading…
Reference in New Issue
Block a user