diff --git a/src/layouts/modules/global-tab/index.vue b/src/layouts/modules/global-tab/index.vue index 2446f133..0be378e8 100644 --- a/src/layouts/modules/global-tab/index.vue +++ b/src/layouts/modules/global-tab/index.vue @@ -26,6 +26,7 @@ const tabRef = ref(); const isPCFlag = isPC(); const TAB_DATA_ID = 'data-tab-id'; +const MIDDLE_MOUSE_BUTTON = 1; type TabNamedNodeMap = NamedNodeMap & { [TAB_DATA_ID]: Attr; @@ -84,6 +85,20 @@ function handleCloseTab(tab: App.Global.Tab) { tabStore.removeTab(tab.id); } +function handleMousedown(e: MouseEvent, tab: App.Global.Tab) { + const isMiddleClick = e.button === MIDDLE_MOUSE_BUTTON; + if (!isMiddleClick || !themeStore.tab.closeTabByMiddleClick) { + return; + } + + if (tabStore.isTabRetain(tab.id)) { + return; + } + + e.preventDefault(); + handleCloseTab(tab); +} + async function refresh() { appStore.reloadPage(500); } @@ -183,6 +198,7 @@ init(); :active-color="themeStore.themeColor" :closable="!tabStore.isTabRetain(tab.id)" @pointerdown="tabStore.switchRouteByTab(tab)" + @mousedown="handleMousedown($event, tab)" @close="handleCloseTab(tab)" @contextmenu="handleContextMenu($event, tab.id)" > diff --git a/src/layouts/modules/theme-drawer/modules/layout/modules/tab-settings.vue b/src/layouts/modules/theme-drawer/modules/layout/modules/tab-settings.vue index bbb87aff..bfa80a6a 100644 --- a/src/layouts/modules/theme-drawer/modules/layout/modules/tab-settings.vue +++ b/src/layouts/modules/theme-drawer/modules/layout/modules/tab-settings.vue @@ -35,6 +35,12 @@ const themeStore = useThemeStore(); class="w-120px" /> + + + + diff --git a/src/locales/langs/en-us.ts b/src/locales/langs/en-us.ts index 523648c1..b51a46a1 100644 --- a/src/locales/langs/en-us.ts +++ b/src/locales/langs/en-us.ts @@ -138,7 +138,9 @@ const local: App.I18n.Schema = { slider: 'Slider', chrome: 'Chrome', button: 'Button' - } + }, + closeByMiddleClick: 'Close Tab by Middle Click', + closeByMiddleClickTip: 'Enable closing tabs by clicking with the middle mouse button' }, header: { title: 'Header Settings', diff --git a/src/locales/langs/zh-cn.ts b/src/locales/langs/zh-cn.ts index 4896f984..f616d4d6 100644 --- a/src/locales/langs/zh-cn.ts +++ b/src/locales/langs/zh-cn.ts @@ -135,7 +135,9 @@ const local: App.I18n.Schema = { slider: '滑块风格', chrome: '谷歌风格', button: '按钮风格' - } + }, + closeByMiddleClick: '鼠标中键关闭标签页', + closeByMiddleClickTip: '启用后可以使用鼠标中键点击标签页进行关闭' }, header: { title: '头部设置', diff --git a/src/theme/settings.ts b/src/theme/settings.ts index 4a4e0a0a..618eff7c 100644 --- a/src/theme/settings.ts +++ b/src/theme/settings.ts @@ -37,7 +37,8 @@ export const themeSettings: App.Theme.ThemeSetting = { visible: true, cache: true, height: 44, - mode: 'chrome' + mode: 'chrome', + closeTabByMiddleClick: false }, fixedHeaderAndTab: true, sider: { diff --git a/src/typings/app.d.ts b/src/typings/app.d.ts index f3d73110..287035cd 100644 --- a/src/typings/app.d.ts +++ b/src/typings/app.d.ts @@ -69,6 +69,8 @@ declare namespace App { height: number; /** Tab mode */ mode: UnionKey.ThemeTabMode; + /** Whether to close tab by middle click */ + closeTabByMiddleClick: boolean; }; /** Fixed header and tab */ fixedHeaderAndTab: boolean; @@ -400,6 +402,8 @@ declare namespace App { cacheTip: string; height: string; mode: { title: string } & Record; + closeByMiddleClick: string; + closeByMiddleClickTip: string; }; header: { title: string;