feat(projects): add page function_tab
This commit is contained in:
parent
7bd1e47af9
commit
6ff86e7777
@ -11,7 +11,9 @@ defineOptions({
|
||||
<div class="flex text-400px text-primary">
|
||||
<SvgIcon local-icon="expectation" />
|
||||
</div>
|
||||
<h3 class="text-28px font-500 text-primary">{{ $t('common.lookForward') }}</h3>
|
||||
<slot>
|
||||
<h3 class="text-28px font-500 text-primary">{{ $t('common.lookForward') }}</h3>
|
||||
</slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -111,6 +111,9 @@ const local: App.I18n.Schema = {
|
||||
home: 'Home',
|
||||
'user-center': 'User Center',
|
||||
about: 'About',
|
||||
function: 'System Function',
|
||||
function_tab: 'Tab',
|
||||
'function_multi-tab': 'Multi Tab',
|
||||
manage: 'System Manage',
|
||||
manage_user: 'User Manage',
|
||||
'manage_user-detail': 'User Detail',
|
||||
@ -211,6 +214,32 @@ const local: App.I18n.Schema = {
|
||||
desc5: 'Soybean just wrote some of the workbench pages casually, and it was enough to see!'
|
||||
},
|
||||
creativity: 'Creativity'
|
||||
},
|
||||
function: {
|
||||
tab: {
|
||||
tabOperate: {
|
||||
title: 'Tab Operation',
|
||||
addTab: 'Add Tab',
|
||||
addTabDesc: 'To about page',
|
||||
closeTab: 'Close Tab',
|
||||
closeCurrentTab: 'Close Current Tab',
|
||||
closeAboutTab: 'Close "About" Tab',
|
||||
addMultiTab: 'Add Multi Tab',
|
||||
addMultiTabDesc1: 'To MultiTab page',
|
||||
addMultiTabDesc2: 'To MultiTab page(with query params)'
|
||||
},
|
||||
tabTitle: {
|
||||
title: 'Tab Title',
|
||||
changeTitle: 'Change Title',
|
||||
change: 'Change',
|
||||
resetTitle: 'Reset Title',
|
||||
reset: 'Reset'
|
||||
}
|
||||
},
|
||||
multiTab: {
|
||||
routeParam: 'Route Param',
|
||||
backTab: 'Back function_tab'
|
||||
}
|
||||
}
|
||||
},
|
||||
form: {
|
||||
|
@ -111,6 +111,9 @@ const local: App.I18n.Schema = {
|
||||
home: '首页',
|
||||
'user-center': '个人中心',
|
||||
about: '关于',
|
||||
function: '系统功能',
|
||||
function_tab: '标签页',
|
||||
'function_multi-tab': '多标签页',
|
||||
manage: '系统管理',
|
||||
manage_user: '用户管理',
|
||||
'manage_user-detail': '用户详情',
|
||||
@ -211,6 +214,32 @@ const local: App.I18n.Schema = {
|
||||
desc5: 'Soybean 刚才把工作台页面随便写了一些,凑合能看了!'
|
||||
},
|
||||
creativity: '创意'
|
||||
},
|
||||
function: {
|
||||
tab: {
|
||||
tabOperate: {
|
||||
title: '标签页操作',
|
||||
addTab: '添加标签页',
|
||||
addTabDesc: '跳转到关于页面',
|
||||
closeTab: '关闭标签页',
|
||||
closeCurrentTab: '关闭当前标签页',
|
||||
closeAboutTab: '关闭"关于"标签页',
|
||||
addMultiTab: '添加多标签页',
|
||||
addMultiTabDesc1: '跳转到多标签页页面',
|
||||
addMultiTabDesc2: '跳转到多标签页页面(带有查询参数)'
|
||||
},
|
||||
tabTitle: {
|
||||
title: '标签页标题',
|
||||
changeTitle: '修改标题',
|
||||
change: '修改',
|
||||
resetTitle: '重置标题',
|
||||
reset: '重置'
|
||||
}
|
||||
},
|
||||
multiTab: {
|
||||
routeParam: '路由参数',
|
||||
backTab: '返回 function_tab'
|
||||
}
|
||||
}
|
||||
},
|
||||
form: {
|
||||
|
@ -20,6 +20,8 @@ export const views: Record<LastLevelRouteKey, RouteComponent | (() => Promise<Ro
|
||||
500: () => import("@/views/_builtin/500/index.vue"),
|
||||
login: () => import("@/views/_builtin/login/index.vue"),
|
||||
about: () => import("@/views/about/index.vue"),
|
||||
"function_multi-tab": () => import("@/views/function/multi-tab/index.vue"),
|
||||
function_tab: () => import("@/views/function/tab/index.vue"),
|
||||
home: () => import("@/views/home/index.vue"),
|
||||
manage_role: () => import("@/views/manage/role/index.vue"),
|
||||
manage_route: () => import("@/views/manage/route/index.vue"),
|
||||
|
@ -47,6 +47,42 @@ export const generatedRoutes: GeneratedRoute[] = [
|
||||
order: 10
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'function',
|
||||
path: '/function',
|
||||
component: 'layout.base',
|
||||
meta: {
|
||||
title: 'function',
|
||||
i18nKey: 'route.function',
|
||||
icon: 'icon-park-outline:all-application',
|
||||
order: 6
|
||||
},
|
||||
children: [
|
||||
{
|
||||
name: 'function_multi-tab',
|
||||
path: '/function/multi-tab',
|
||||
component: 'view.function_multi-tab',
|
||||
meta: {
|
||||
title: 'function_multi-tab',
|
||||
i18nKey: 'route.function_multi-tab',
|
||||
icon: 'ic:round-tab',
|
||||
multiTab: true,
|
||||
hideInMenu: true,
|
||||
activeMenu: 'function_tab'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'function_tab',
|
||||
path: '/function/tab',
|
||||
component: 'view.function_tab',
|
||||
meta: {
|
||||
title: 'function_tab',
|
||||
i18nKey: 'route.function_tab',
|
||||
icon: 'ic:round-tab'
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'home',
|
||||
path: '/home',
|
||||
|
@ -151,6 +151,9 @@ const routeMap: RouteMap = {
|
||||
"404": "/404",
|
||||
"500": "/500",
|
||||
"about": "/about",
|
||||
"function": "/function",
|
||||
"function_multi-tab": "/function/multi-tab",
|
||||
"function_tab": "/function/tab",
|
||||
"home": "/home",
|
||||
"login": "/login/:module(pwd-login|code-login|register|reset-pwd|bind-wechat)?",
|
||||
"manage": "/manage",
|
||||
|
@ -2,6 +2,7 @@ import { computed, ref } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { defineStore } from 'pinia';
|
||||
import { useEventListener } from '@vueuse/core';
|
||||
import type { RouteKey } from '@elegant-router/types';
|
||||
import { SetupStoreId } from '@/enum';
|
||||
import { useRouterPush } from '@/hooks/common/router';
|
||||
import { localStg } from '@/utils/storage';
|
||||
@ -10,6 +11,7 @@ import {
|
||||
filterTabsByAllRoutes,
|
||||
filterTabsById,
|
||||
filterTabsByIds,
|
||||
findTabByRouteName,
|
||||
getAllTabs,
|
||||
getDefaultHomeTab,
|
||||
getFixedTabIds,
|
||||
@ -112,6 +114,23 @@ export const useTabStore = defineStore(SetupStoreId.Tab, () => {
|
||||
}
|
||||
}
|
||||
|
||||
/** remove active tab */
|
||||
async function removeActiveTab() {
|
||||
await removeTab(activeTabId.value);
|
||||
}
|
||||
|
||||
/**
|
||||
* remove tab by route name
|
||||
*
|
||||
* @param routeName route name
|
||||
*/
|
||||
async function removeTabByRouteName(routeName: RouteKey) {
|
||||
const tab = findTabByRouteName(routeName, tabs.value);
|
||||
if (!tab) return;
|
||||
|
||||
await removeTab(tab.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear tabs
|
||||
*
|
||||
@ -192,6 +211,7 @@ export const useTabStore = defineStore(SetupStoreId.Tab, () => {
|
||||
const tab = tabs.value.find(item => item.id === id);
|
||||
if (!tab) return;
|
||||
|
||||
tab.oldLabel = tab.label;
|
||||
tab.newLabel = label;
|
||||
}
|
||||
|
||||
@ -252,6 +272,8 @@ export const useTabStore = defineStore(SetupStoreId.Tab, () => {
|
||||
initTabStore,
|
||||
addTab,
|
||||
removeTab,
|
||||
removeActiveTab,
|
||||
removeTabByRouteName,
|
||||
clearTabs,
|
||||
clearLeftTabs,
|
||||
clearRightTabs,
|
||||
|
@ -1,5 +1,5 @@
|
||||
import type { Router } from 'vue-router';
|
||||
import type { LastLevelRouteKey, RouteMap } from '@elegant-router/types';
|
||||
import type { LastLevelRouteKey, RouteKey, RouteMap } from '@elegant-router/types';
|
||||
import { $t } from '@/locales';
|
||||
import { getRoutePath } from '@/router/elegant/transform';
|
||||
|
||||
@ -166,10 +166,12 @@ export function getFixedTabIds(tabs: App.Global.Tab[]) {
|
||||
* @param tabs
|
||||
*/
|
||||
function updateTabsLabel(tabs: App.Global.Tab[]) {
|
||||
return tabs.map(tab => ({
|
||||
const updated = tabs.map(tab => ({
|
||||
...tab,
|
||||
label: tab.newLabel || tab.label
|
||||
label: tab.newLabel || tab.oldLabel || tab.label
|
||||
}));
|
||||
|
||||
return updated;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -194,3 +196,18 @@ export function updateTabByI18nKey(tab: App.Global.Tab) {
|
||||
export function updateTabsByI18nKey(tabs: App.Global.Tab[]) {
|
||||
return tabs.map(tab => updateTabByI18nKey(tab));
|
||||
}
|
||||
|
||||
/**
|
||||
* find tab by route name
|
||||
*
|
||||
* @param name
|
||||
* @param tabs
|
||||
*/
|
||||
export function findTabByRouteName(name: RouteKey, tabs: App.Global.Tab[]) {
|
||||
const routePath = getRoutePath(name);
|
||||
|
||||
const tabId = routePath;
|
||||
const multiTabId = `${routePath}?`;
|
||||
|
||||
return tabs.find(tab => tab.id === tabId || tab.id.startsWith(multiTabId));
|
||||
}
|
||||
|
32
src/typings/app.d.ts
vendored
32
src/typings/app.d.ts
vendored
@ -185,6 +185,12 @@ declare namespace App {
|
||||
* If set, the tab label will be replaced by this value
|
||||
*/
|
||||
newLabel?: string;
|
||||
/**
|
||||
* The old tab label
|
||||
*
|
||||
* when reset the tab label, the tab label will be replaced by this value
|
||||
*/
|
||||
oldLabel?: string;
|
||||
/** The tab route key */
|
||||
routeKey: LastLevelRouteKey;
|
||||
/** The tab route path */
|
||||
@ -396,6 +402,32 @@ declare namespace App {
|
||||
};
|
||||
creativity: string;
|
||||
};
|
||||
function: {
|
||||
tab: {
|
||||
tabOperate: {
|
||||
title: string;
|
||||
addTab: string;
|
||||
addTabDesc: string;
|
||||
closeTab: string;
|
||||
closeCurrentTab: string;
|
||||
closeAboutTab: string;
|
||||
addMultiTab: string;
|
||||
addMultiTabDesc1: string;
|
||||
addMultiTabDesc2: string;
|
||||
};
|
||||
tabTitle: {
|
||||
title: string;
|
||||
changeTitle: string;
|
||||
change: string;
|
||||
resetTitle: string;
|
||||
reset: string;
|
||||
};
|
||||
};
|
||||
multiTab: {
|
||||
routeParam: string;
|
||||
backTab: string;
|
||||
};
|
||||
};
|
||||
};
|
||||
form: {
|
||||
userName: FormMsg;
|
||||
|
1
src/typings/components.d.ts
vendored
1
src/typings/components.d.ts
vendored
@ -41,6 +41,7 @@ declare module 'vue' {
|
||||
NGrid: typeof import('naive-ui')['NGrid']
|
||||
NGridItem: typeof import('naive-ui')['NGridItem']
|
||||
NInput: typeof import('naive-ui')['NInput']
|
||||
NInputGroup: typeof import('naive-ui')['NInputGroup']
|
||||
NInputNumber: typeof import('naive-ui')['NInputNumber']
|
||||
NList: typeof import('naive-ui')['NList']
|
||||
NListItem: typeof import('naive-ui')['NListItem']
|
||||
|
6
src/typings/elegant-router.d.ts
vendored
6
src/typings/elegant-router.d.ts
vendored
@ -25,6 +25,9 @@ declare module "@elegant-router/types" {
|
||||
"404": "/404";
|
||||
"500": "/500";
|
||||
"about": "/about";
|
||||
"function": "/function";
|
||||
"function_multi-tab": "/function/multi-tab";
|
||||
"function_tab": "/function/tab";
|
||||
"home": "/home";
|
||||
"login": "/login/:module(pwd-login|code-login|register|reset-pwd|bind-wechat)?";
|
||||
"manage": "/manage";
|
||||
@ -78,6 +81,7 @@ declare module "@elegant-router/types" {
|
||||
| "404"
|
||||
| "500"
|
||||
| "about"
|
||||
| "function"
|
||||
| "home"
|
||||
| "login"
|
||||
| "manage"
|
||||
@ -105,6 +109,8 @@ declare module "@elegant-router/types" {
|
||||
| "500"
|
||||
| "login"
|
||||
| "about"
|
||||
| "function_multi-tab"
|
||||
| "function_tab"
|
||||
| "home"
|
||||
| "manage_role"
|
||||
| "manage_route"
|
||||
|
24
src/views/function/multi-tab/index.vue
Normal file
24
src/views/function/multi-tab/index.vue
Normal file
@ -0,0 +1,24 @@
|
||||
<script setup lang="ts">
|
||||
import { useRoute } from 'vue-router';
|
||||
import { computed } from 'vue';
|
||||
import { useRouterPush } from '@/hooks/common/router';
|
||||
import { $t } from '@/locales';
|
||||
|
||||
const route = useRoute();
|
||||
const { routerPushByKey } = useRouterPush();
|
||||
|
||||
const routeQuery = computed(() => JSON.stringify(route.query));
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<LookForward>
|
||||
<div>
|
||||
<NButton @click="routerPushByKey('function_tab')">{{ $t('page.function.multiTab.backTab') }}</NButton>
|
||||
<div class="py-24px">{{ $t('page.function.multiTab.routeParam') }}: {{ routeQuery }}</div>
|
||||
</div>
|
||||
</LookForward>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
88
src/views/function/tab/index.vue
Normal file
88
src/views/function/tab/index.vue
Normal file
@ -0,0 +1,88 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { useRouterPush } from '@/hooks/common/router';
|
||||
import { $t } from '@/locales';
|
||||
import { useTabStore } from '@/store/modules/tab';
|
||||
|
||||
const tabStore = useTabStore();
|
||||
const { routerPushByKey } = useRouterPush();
|
||||
|
||||
const tabLabel = ref('');
|
||||
|
||||
function changeTabLabel() {
|
||||
tabStore.setTabLabel(tabLabel.value);
|
||||
}
|
||||
|
||||
function resetTabLabel() {
|
||||
tabStore.resetTabLabel();
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NSpace vertical :size="16">
|
||||
<NCard
|
||||
:title="$t('page.function.tab.tabOperate.title')"
|
||||
:bordered="false"
|
||||
size="small"
|
||||
segmented
|
||||
class="card-wrapper"
|
||||
>
|
||||
<NList>
|
||||
<NListItem>
|
||||
<NThing :title="$t('page.function.tab.tabOperate.addTab')">
|
||||
<NButton @click="routerPushByKey('about')">{{ $t('page.function.tab.tabOperate.addTabDesc') }}</NButton>
|
||||
</NThing>
|
||||
</NListItem>
|
||||
<NListItem>
|
||||
<NThing :title="$t('page.function.tab.tabOperate.closeTab')">
|
||||
<NSpace>
|
||||
<NButton @click="tabStore.removeActiveTab">
|
||||
{{ $t('page.function.tab.tabOperate.closeCurrentTab') }}
|
||||
</NButton>
|
||||
<NButton @click="tabStore.removeTabByRouteName('about')">
|
||||
{{ $t('page.function.tab.tabOperate.closeAboutTab') }}
|
||||
</NButton>
|
||||
</NSpace>
|
||||
</NThing>
|
||||
</NListItem>
|
||||
<NListItem>
|
||||
<NThing :title="$t('page.function.tab.tabOperate.addMultiTab')">
|
||||
<NSpace>
|
||||
<NButton @click="routerPushByKey('function_multi-tab')">
|
||||
{{ $t('page.function.tab.tabOperate.addMultiTabDesc1') }}
|
||||
</NButton>
|
||||
<NButton @click="routerPushByKey('function_multi-tab', { query: { a: '1' } })">
|
||||
{{ $t('page.function.tab.tabOperate.addMultiTabDesc2') }}
|
||||
</NButton>
|
||||
</NSpace>
|
||||
</NThing>
|
||||
</NListItem>
|
||||
</NList>
|
||||
</NCard>
|
||||
<NCard
|
||||
:title="$t('page.function.tab.tabTitle.title')"
|
||||
:bordered="false"
|
||||
size="small"
|
||||
segmented
|
||||
class="card-wrapper"
|
||||
>
|
||||
<NList>
|
||||
<NListItem>
|
||||
<NThing :title="$t('page.function.tab.tabTitle.changeTitle')">
|
||||
<NInputGroup class="w-240px">
|
||||
<NInput v-model:value="tabLabel" />
|
||||
<NButton @click="changeTabLabel">{{ $t('page.function.tab.tabTitle.change') }}</NButton>
|
||||
</NInputGroup>
|
||||
</NThing>
|
||||
</NListItem>
|
||||
<NListItem>
|
||||
<NThing :title="$t('page.function.tab.tabTitle.resetTitle')">
|
||||
<NButton @click="resetTabLabel">{{ $t('page.function.tab.tabTitle.reset') }}</NButton>
|
||||
</NThing>
|
||||
</NListItem>
|
||||
</NList>
|
||||
</NCard>
|
||||
</NSpace>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
Loading…
Reference in New Issue
Block a user