chore: detail optimization
This commit is contained in:
parent
7437896034
commit
31e2715e67
|
|
@ -74,9 +74,7 @@ function injectCdnjs(html: string) {
|
||||||
export async function runUpdateHtml() {
|
export async function runUpdateHtml() {
|
||||||
const outDir = viteConfig.outDir || 'dist';
|
const outDir = viteConfig.outDir || 'dist';
|
||||||
const indexPath = getCwdPath(outDir, 'index.html');
|
const indexPath = getCwdPath(outDir, 'index.html');
|
||||||
if (!existsSync(`${indexPath}`)) {
|
if (!existsSync(indexPath)) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
let processedHtml = '';
|
let processedHtml = '';
|
||||||
const rawHtml = readFileSync(indexPath, 'utf-8');
|
const rawHtml = readFileSync(indexPath, 'utf-8');
|
||||||
|
|
@ -92,7 +90,9 @@ export async function runUpdateHtml() {
|
||||||
}
|
}
|
||||||
if (minify) {
|
if (minify) {
|
||||||
const { enable, ...miniOpt } = minify;
|
const { enable, ...miniOpt } = minify;
|
||||||
processedHtml = HtmlMinifier.minify(processedHtml, miniOpt);
|
if (enable) {
|
||||||
|
processedHtml = HtmlMinifier.minify(processedHtml, miniOpt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
writeFileSync(indexPath, processedHtml);
|
writeFileSync(indexPath, processedHtml);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,95 @@
|
||||||
|
// https://github.com/luxueyan/vite-transform-globby-import/blob/master/src/index.ts
|
||||||
|
|
||||||
|
// TODO 目前还不能监听文件新增及删除 内容已经改变,缓存问题?
|
||||||
|
// 可以使用,先不打算集成
|
||||||
|
import { join } from 'path';
|
||||||
|
import { lstatSync } from 'fs';
|
||||||
|
import glob from 'glob';
|
||||||
|
import { createResolver, Resolver } from 'vite/dist/node/resolver.js';
|
||||||
|
import { Transform } from 'vite/dist/node/transform.js';
|
||||||
|
|
||||||
|
const modulesDir: string = join(process.cwd(), '/node_modules/');
|
||||||
|
|
||||||
|
interface SharedConfig {
|
||||||
|
root?: string;
|
||||||
|
alias?: Record<string, string>;
|
||||||
|
resolvers?: Resolver[];
|
||||||
|
}
|
||||||
|
|
||||||
|
function template(template: string) {
|
||||||
|
return (data: { [x: string]: any }) => {
|
||||||
|
return template.replace(/#([^#]+)#/g, (_, g1) => data[g1] || g1);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const globbyTransform = function (config: SharedConfig): Transform {
|
||||||
|
const resolver = createResolver(
|
||||||
|
config.root || process.cwd(),
|
||||||
|
config.resolvers || [],
|
||||||
|
config.alias || {}
|
||||||
|
);
|
||||||
|
const cache = new Map();
|
||||||
|
|
||||||
|
const urlMap = new Map();
|
||||||
|
return {
|
||||||
|
test({ path }) {
|
||||||
|
const filePath = path.replace('\u0000', ''); // why some path startsWith '\u0000'?
|
||||||
|
try {
|
||||||
|
return (
|
||||||
|
!filePath.startsWith(modulesDir) &&
|
||||||
|
/\.(vue|js|jsx|ts|tsx)$/.test(filePath) &&
|
||||||
|
lstatSync(filePath).isFile()
|
||||||
|
);
|
||||||
|
} catch {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
transform({ code, path, isBuild }) {
|
||||||
|
let result = cache.get(path);
|
||||||
|
if (!result) {
|
||||||
|
const reg = /import\s+([\w\s{}*]+)\s+from\s+(['"])globby(\?path)?!([^'"]+)\2/g;
|
||||||
|
const lastImport = urlMap.get(path);
|
||||||
|
const match = code.match(reg);
|
||||||
|
if (lastImport && match) {
|
||||||
|
code = code.replace(lastImport, match[0]);
|
||||||
|
}
|
||||||
|
result = code.replace(reg, (_, g1, g2, g3, g4) => {
|
||||||
|
const filePath = path.replace('\u0000', ''); // why some path startsWith '\u0000'?
|
||||||
|
// resolve path
|
||||||
|
const resolvedFilePath = g4.startsWith('.')
|
||||||
|
? resolver.resolveRelativeRequest(filePath, g4)
|
||||||
|
: { pathname: resolver.requestToFile(g4) };
|
||||||
|
const files = glob.sync(resolvedFilePath.pathname, { dot: true });
|
||||||
|
let templateStr = 'import #name# from #file#'; // import default
|
||||||
|
let name = g1;
|
||||||
|
const m = g1.match(/\{\s*(\w+)(\s+as\s+(\w+))?\s*\}/); // import module
|
||||||
|
const m2 = g1.match(/\*\s+as\s+(\w+)/); // import * as all module
|
||||||
|
if (m) {
|
||||||
|
templateStr = `import { ${m[1]} as #name# } from #file#`;
|
||||||
|
name = m[3] || m[1];
|
||||||
|
} else if (m2) {
|
||||||
|
templateStr = 'import * as #name# from #file#';
|
||||||
|
name = m2[1];
|
||||||
|
}
|
||||||
|
const temRender = template(templateStr);
|
||||||
|
|
||||||
|
const groups: Array<string>[] = [];
|
||||||
|
const replaceFiles = files.map((f, i) => {
|
||||||
|
const file = g2 + resolver.fileToRequest(f) + g2;
|
||||||
|
groups.push([name + i, file]);
|
||||||
|
return temRender({ name: name + i, file });
|
||||||
|
});
|
||||||
|
urlMap.set(path, replaceFiles.join('\n'));
|
||||||
|
return (
|
||||||
|
replaceFiles.join('\n') +
|
||||||
|
(g3 ? '\n' + groups.map((v) => `${v[0]}._path = ${v[1]}`).join('\n') : '') +
|
||||||
|
`\nconst ${name} = { ${groups.map((v) => v[0]).join(',')} }\n`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
if (isBuild) cache.set(path, result);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
export default globbyTransform;
|
||||||
|
|
@ -124,28 +124,24 @@ export function getEnvConfig(match = 'VITE_GLOB_', confFiles = ['.env', '.env.pr
|
||||||
return envConfig;
|
return envConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function successConsole(message: any) {
|
function consoleFn(color: string, message: any) {
|
||||||
console.log(
|
console.log(
|
||||||
chalk.blue.bold('**************** ') +
|
chalk.blue.bold('**************** ') +
|
||||||
chalk.green.bold('✨ ' + message) +
|
(chalk as any)[color].bold(message) +
|
||||||
chalk.blue.bold(' ****************')
|
chalk.blue.bold(' ****************')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function successConsole(message: any) {
|
||||||
|
consoleFn('green', '✨ ' + message);
|
||||||
|
}
|
||||||
|
|
||||||
export function errorConsole(message: any) {
|
export function errorConsole(message: any) {
|
||||||
console.log(
|
consoleFn('red', '✨ ' + message);
|
||||||
chalk.blue.bold('**************** ') +
|
|
||||||
chalk.red.bold('✨ ' + message) +
|
|
||||||
chalk.blue.bold(' ****************')
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function warnConsole(message: any) {
|
export function warnConsole(message: any) {
|
||||||
console.log(
|
consoleFn('yellow', '✨ ' + message);
|
||||||
chalk.blue.bold('**************** ') +
|
|
||||||
chalk.yellow.bold('✨ ' + message) +
|
|
||||||
chalk.blue.bold(' ****************')
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getCwdPath(...dir: string[]) {
|
export function getCwdPath(...dir: string[]) {
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, reactive, computed, watch, onMounted, unref, toRef } from 'vue';
|
import { defineComponent, reactive, computed, watch, onMounted, unref, toRef } from 'vue';
|
||||||
|
|
||||||
import { countToProps } from './props';
|
import { countToProps } from './props';
|
||||||
import { useRaf } from '/@/hooks/event/useRaf';
|
import { useRaf } from '/@/hooks/event/useRaf';
|
||||||
import { isNumber } from '/@/utils/is';
|
import { isNumber } from '/@/utils/is';
|
||||||
|
|
@ -37,12 +36,14 @@
|
||||||
remaining: null,
|
remaining: null,
|
||||||
rAF: null,
|
rAF: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
if (props.autoplay) {
|
if (props.autoplay) {
|
||||||
start();
|
start();
|
||||||
}
|
}
|
||||||
emit('mounted');
|
emit('mounted');
|
||||||
});
|
});
|
||||||
|
|
||||||
const getCountDown = computed(() => {
|
const getCountDown = computed(() => {
|
||||||
return props.startVal > props.endVal;
|
return props.startVal > props.endVal;
|
||||||
});
|
});
|
||||||
|
|
@ -61,6 +62,7 @@
|
||||||
state.paused = false;
|
state.paused = false;
|
||||||
state.rAF = requestAnimationFrame(count);
|
state.rAF = requestAnimationFrame(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
function pauseResume() {
|
function pauseResume() {
|
||||||
if (state.paused) {
|
if (state.paused) {
|
||||||
resume();
|
resume();
|
||||||
|
|
@ -70,6 +72,7 @@
|
||||||
state.paused = true;
|
state.paused = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function pause() {
|
function pause() {
|
||||||
cancelAnimationFrame(state.rAF);
|
cancelAnimationFrame(state.rAF);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import { Menu } from 'ant-design-vue';
|
||||||
import { MenuModeEnum, MenuTypeEnum } from '/@/enums/menuEnum';
|
import { MenuModeEnum, MenuTypeEnum } from '/@/enums/menuEnum';
|
||||||
import { menuStore } from '/@/store/modules/menu';
|
import { menuStore } from '/@/store/modules/menu';
|
||||||
import { getSlot } from '/@/utils/helper/tsxHelper';
|
import { getSlot } from '/@/utils/helper/tsxHelper';
|
||||||
import { ScrollContainer } from '/@/components/Container/index';
|
// import { ScrollContainer } from '/@/components/Container/index';
|
||||||
import SearchInput from './SearchInput.vue';
|
import SearchInput from './SearchInput.vue';
|
||||||
import './index.less';
|
import './index.less';
|
||||||
import { menuHasChildren } from './helper';
|
import { menuHasChildren } from './helper';
|
||||||
|
|
@ -67,6 +67,7 @@ export default defineComponent({
|
||||||
return {
|
return {
|
||||||
height: `calc(100% - ${offset}px)`,
|
height: `calc(100% - ${offset}px)`,
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
|
overflow: 'auto',
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -246,8 +247,9 @@ export default defineComponent({
|
||||||
onClick={handleInputClick}
|
onClick={handleInputClick}
|
||||||
collapsed={getCollapsedState}
|
collapsed={getCollapsedState}
|
||||||
/>
|
/>
|
||||||
<section style={unref(getMenuWrapStyle)}>
|
<section style={unref(getMenuWrapStyle)} class="basic-menu__wrap">
|
||||||
<ScrollContainer>{() => renderMenu()}</ScrollContainer>
|
{renderMenu()}
|
||||||
|
{/* <ScrollContainer>{() => renderMenu()}</ScrollContainer> */}
|
||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,30 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.basic-menu {
|
.basic-menu {
|
||||||
|
&__wrap {
|
||||||
|
/* 滚动槽 */
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
width: 6px;
|
||||||
|
height: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO 滚动条样式-待修改
|
||||||
|
&::-webkit-scrollbar-track {
|
||||||
|
background: rgba(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 滚动条滑块 */
|
||||||
|
&::-webkit-scrollbar-thumb {
|
||||||
|
background: rgba(255, 255, 255, 0.3);
|
||||||
|
border-radius: 4px;
|
||||||
|
box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: @border-color-dark;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.ant-menu-submenu:first-of-type {
|
.ant-menu-submenu:first-of-type {
|
||||||
margin-top: 4px;
|
margin-top: 4px;
|
||||||
}
|
}
|
||||||
|
|
@ -95,14 +119,14 @@
|
||||||
.ant-menu-submenu-active,
|
.ant-menu-submenu-active,
|
||||||
.ant-menu-submenu-title:hover {
|
.ant-menu-submenu-title:hover {
|
||||||
background: @top-menu-active-bg-color;
|
background: @top-menu-active-bg-color;
|
||||||
border-radius: 6px 6px 0 0;
|
// border-radius: 6px 6px 0 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.basic-menu-item__level1 {
|
.basic-menu-item__level1 {
|
||||||
&.ant-menu-item-selected,
|
&.ant-menu-item-selected,
|
||||||
&.ant-menu-submenu-selected {
|
&.ant-menu-submenu-selected {
|
||||||
background: @top-menu-active-bg-color;
|
background: @top-menu-active-bg-color;
|
||||||
border-radius: 6px 6px 0 0;
|
// border-radius: 6px 6px 0 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -148,6 +172,10 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.basic-menu-item__level1 {
|
.basic-menu-item__level1 {
|
||||||
|
> .ant-menu-sub > li {
|
||||||
|
background-color: @sub-menu-item-dark-bg-color;
|
||||||
|
}
|
||||||
|
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
|
|
||||||
&.top-active-menu {
|
&.top-active-menu {
|
||||||
|
|
@ -179,7 +207,7 @@
|
||||||
|
|
||||||
.ant-menu-submenu-title {
|
.ant-menu-submenu-title {
|
||||||
height: @app-menu-item-height;
|
height: @app-menu-item-height;
|
||||||
margin: 0;
|
// margin: 0;
|
||||||
line-height: @app-menu-item-height;
|
line-height: @app-menu-item-height;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,4 +18,4 @@
|
||||||
// app menu
|
// app menu
|
||||||
|
|
||||||
// left-menu
|
// left-menu
|
||||||
@app-menu-item-height: 44px;
|
@app-menu-item-height: 48px;
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
import type { AppRouteRecordRaw } from '/@/router/types.d';
|
|
||||||
import { useTimeout } from '/@/hooks/core/useTimeout';
|
import { useTimeout } from '/@/hooks/core/useTimeout';
|
||||||
import { PageEnum } from '/@/enums/pageEnum';
|
import { PageEnum } from '/@/enums/pageEnum';
|
||||||
import { TabItem, tabStore } from '/@/store/modules/tab';
|
import { TabItem, tabStore } from '/@/store/modules/tab';
|
||||||
import { appStore } from '/@/store/modules/app';
|
import { appStore } from '/@/store/modules/app';
|
||||||
import router from '/@/router';
|
import router from '/@/router';
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
|
import { pathToRegexp } from 'path-to-regexp';
|
||||||
|
|
||||||
const activeKeyRef = ref<string>('');
|
const activeKeyRef = ref<string>('');
|
||||||
|
|
||||||
|
|
@ -68,7 +68,11 @@ export function useTabs() {
|
||||||
function getTo(path: string): any {
|
function getTo(path: string): any {
|
||||||
const routes = router.getRoutes();
|
const routes = router.getRoutes();
|
||||||
const fn = (p: string): any => {
|
const fn = (p: string): any => {
|
||||||
const to = routes.find((item) => item.path === p);
|
const to = routes.find((item) => {
|
||||||
|
if (item.path === '/:path(.*)*') return;
|
||||||
|
const regexp = pathToRegexp(item.path);
|
||||||
|
return regexp.test(p);
|
||||||
|
});
|
||||||
if (!to) return '';
|
if (!to) return '';
|
||||||
if (!to.redirect) return to;
|
if (!to.redirect) return to;
|
||||||
if (to.redirect) {
|
if (to.redirect) {
|
||||||
|
|
@ -88,12 +92,13 @@ export function useTabs() {
|
||||||
resetCache: () => canIUseFn() && resetCache(),
|
resetCache: () => canIUseFn() && resetCache(),
|
||||||
addTab: (path: PageEnum, goTo = false, replace = false) => {
|
addTab: (path: PageEnum, goTo = false, replace = false) => {
|
||||||
const to = getTo(path);
|
const to = getTo(path);
|
||||||
|
|
||||||
if (!to) return;
|
if (!to) return;
|
||||||
useTimeout(() => {
|
useTimeout(() => {
|
||||||
tabStore.addTabByPathAction((to as unknown) as AppRouteRecordRaw);
|
tabStore.addTabByPathAction();
|
||||||
}, 0);
|
}, 0);
|
||||||
activeKeyRef.value = to.path;
|
activeKeyRef.value = path;
|
||||||
goTo && replace ? router.replace : router.push(to.path);
|
goTo && replace ? router.replace : router.push(path);
|
||||||
},
|
},
|
||||||
activeKeyRef,
|
activeKeyRef,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -82,10 +82,13 @@ export default defineComponent({
|
||||||
{() => (
|
{() => (
|
||||||
<>
|
<>
|
||||||
{isLock && <LockPage />}
|
{isLock && <LockPage />}
|
||||||
|
|
||||||
{!unref(getFullContent) && unref(isShowMixHeaderRef) && unref(showHeaderRef) && (
|
{!unref(getFullContent) && unref(isShowMixHeaderRef) && unref(showHeaderRef) && (
|
||||||
<LayoutHeader />
|
<LayoutHeader />
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{showSettingButton && <SettingBtn />}
|
{showSettingButton && <SettingBtn />}
|
||||||
|
|
||||||
<Layout>
|
<Layout>
|
||||||
{() => (
|
{() => (
|
||||||
<>
|
<>
|
||||||
|
|
@ -102,7 +105,9 @@ export default defineComponent({
|
||||||
{() => <MultipleTabs />}
|
{() => <MultipleTabs />}
|
||||||
</Layout.Header>
|
</Layout.Header>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{useOpenBackTop && <BackTop target={getTarget} />}
|
{useOpenBackTop && <BackTop target={getTarget} />}
|
||||||
|
|
||||||
<div class={[`default-layout__main`, fixedHeaderCls]}>
|
<div class={[`default-layout__main`, fixedHeaderCls]}>
|
||||||
{openPageLoading && (
|
{openPageLoading && (
|
||||||
<FullLoading
|
<FullLoading
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import {
|
||||||
// ref,
|
// ref,
|
||||||
unref,
|
unref,
|
||||||
onMounted,
|
onMounted,
|
||||||
|
toRaw,
|
||||||
} from 'vue';
|
} from 'vue';
|
||||||
import { Tabs } from 'ant-design-vue';
|
import { Tabs } from 'ant-design-vue';
|
||||||
import TabContent from './TabContent';
|
import TabContent from './TabContent';
|
||||||
|
|
@ -73,11 +74,7 @@ export default defineComponent({
|
||||||
routes &&
|
routes &&
|
||||||
routes.forEach((route) => {
|
routes.forEach((route) => {
|
||||||
if (route.meta && route.meta.affix) {
|
if (route.meta && route.meta.affix) {
|
||||||
tabs.push({
|
tabs.push(toRaw(route) as TabItem);
|
||||||
path: route.path,
|
|
||||||
name: route.name,
|
|
||||||
meta: { ...route.meta },
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return tabs;
|
return tabs;
|
||||||
|
|
@ -114,7 +111,7 @@ export default defineComponent({
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<span>
|
<span>
|
||||||
<TabContent {...tabContentProps} />
|
<TabContent {...(tabContentProps as any)} />
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,8 @@ export default defineComponent({
|
||||||
<RouterView>
|
<RouterView>
|
||||||
{{
|
{{
|
||||||
default: ({ Component, route }: { Component: any; route: RouteLocation }) => {
|
default: ({ Component, route }: { Component: any; route: RouteLocation }) => {
|
||||||
const name = route.meta.inTab ? ' ' : null;
|
// 已经位于tab内的不再显示动画
|
||||||
|
const name = route.meta.inTab ? 'fade' : null;
|
||||||
const Content = openCache ? (
|
const Content = openCache ? (
|
||||||
<KeepAlive max={max} include={cacheTabs}>
|
<KeepAlive max={max} include={cacheTabs}>
|
||||||
<Component {...route.params} />
|
<Component {...route.params} />
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import { createProgressGuard } from './progressGuard';
|
||||||
import { createPermissionGuard } from './permissionGuard';
|
import { createPermissionGuard } from './permissionGuard';
|
||||||
import { createPageLoadingGuard } from './pageLoadingGuard';
|
import { createPageLoadingGuard } from './pageLoadingGuard';
|
||||||
import { useSetting } from '/@/hooks/core/useSetting';
|
import { useSetting } from '/@/hooks/core/useSetting';
|
||||||
import { getIsOpenTab } from '/@/utils/helper/routeHelper';
|
import { getIsOpenTab, setCurrentTo } from '/@/utils/helper/routeHelper';
|
||||||
|
|
||||||
const { projectSetting } = useSetting();
|
const { projectSetting } = useSetting();
|
||||||
export function createGuard(router: Router) {
|
export function createGuard(router: Router) {
|
||||||
|
|
@ -17,7 +17,7 @@ export function createGuard(router: Router) {
|
||||||
axiosCanceler = new AxiosCanceler();
|
axiosCanceler = new AxiosCanceler();
|
||||||
}
|
}
|
||||||
router.beforeEach(async (to) => {
|
router.beforeEach(async (to) => {
|
||||||
const isOpen = getIsOpenTab(to.path);
|
const isOpen = getIsOpenTab(to.fullPath);
|
||||||
to.meta.inTab = isOpen;
|
to.meta.inTab = isOpen;
|
||||||
try {
|
try {
|
||||||
if (closeMessageOnSwitch) {
|
if (closeMessageOnSwitch) {
|
||||||
|
|
@ -30,6 +30,8 @@ export function createGuard(router: Router) {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn('basic guard error:' + error);
|
console.warn('basic guard error:' + error);
|
||||||
}
|
}
|
||||||
|
setCurrentTo(to);
|
||||||
|
return true;
|
||||||
});
|
});
|
||||||
openNProgress && createProgressGuard(router);
|
openNProgress && createProgressGuard(router);
|
||||||
createPermissionGuard(router);
|
createPermissionGuard(router);
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import type { Router } from 'vue-router';
|
||||||
import { tabStore } from '/@/store/modules/tab';
|
import { tabStore } from '/@/store/modules/tab';
|
||||||
import { appStore } from '/@/store/modules/app';
|
import { appStore } from '/@/store/modules/app';
|
||||||
import { userStore } from '/@/store/modules/user';
|
import { userStore } from '/@/store/modules/user';
|
||||||
|
import { getParams } from '/@/utils/helper/routeHelper';
|
||||||
|
|
||||||
export function createPageLoadingGuard(router: Router) {
|
export function createPageLoadingGuard(router: Router) {
|
||||||
let isFirstLoad = true;
|
let isFirstLoad = true;
|
||||||
|
|
@ -29,9 +30,16 @@ export function createPageLoadingGuard(router: Router) {
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
router.afterEach(async (to) => {
|
router.afterEach(async (to, from) => {
|
||||||
const { openRouterTransition, openPageLoading } = appStore.getProjectConfig;
|
const { openRouterTransition, openPageLoading } = appStore.getProjectConfig;
|
||||||
if ((!openRouterTransition && openPageLoading) || isFirstLoad || to.meta.afterCloseLoading) {
|
const realToPath = to.path.replace(getParams(to), '');
|
||||||
|
const realFormPath = from.path.replace(getParams(from), '');
|
||||||
|
if (
|
||||||
|
(!openRouterTransition && openPageLoading) ||
|
||||||
|
isFirstLoad ||
|
||||||
|
to.meta.afterCloseLoading ||
|
||||||
|
realToPath === realFormPath
|
||||||
|
) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
appStore.commitPageLoadingState(false);
|
appStore.commitPageLoadingState(false);
|
||||||
}, 110);
|
}, 110);
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,8 @@ export async function getFlatChildrenMenus(children: Menu[]) {
|
||||||
function basicFilter(routes: RouteRecordNormalized[]) {
|
function basicFilter(routes: RouteRecordNormalized[]) {
|
||||||
return (menu: Menu) => {
|
return (menu: Menu) => {
|
||||||
const matchRoute = routes.find((route) => route.path === menu.path);
|
const matchRoute = routes.find((route) => route.path === menu.path);
|
||||||
if (!matchRoute) return false;
|
|
||||||
|
if (!matchRoute) return true;
|
||||||
menu.icon = menu.icon || matchRoute.meta.icon;
|
menu.icon = menu.icon || matchRoute.meta.icon;
|
||||||
menu.meta = matchRoute.meta;
|
menu.meta = matchRoute.meta;
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,20 @@ const menu: MenuModule = {
|
||||||
path: '/full-screen',
|
path: '/full-screen',
|
||||||
name: '全屏',
|
name: '全屏',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/testTab',
|
||||||
|
name: '带参Tab',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: '/id1',
|
||||||
|
name: '带参tab1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/id2',
|
||||||
|
name: '带参tab2',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,6 @@ import type { AppRouteRecordRaw, AppRouteModule } from '/@/router/types';
|
||||||
import { DEFAULT_LAYOUT_COMPONENT, PAGE_NOT_FOUND_ROUTE, REDIRECT_ROUTE } from '../constant';
|
import { DEFAULT_LAYOUT_COMPONENT, PAGE_NOT_FOUND_ROUTE, REDIRECT_ROUTE } from '../constant';
|
||||||
import { genRouteModule } from '/@/utils/helper/routeHelper';
|
import { genRouteModule } from '/@/utils/helper/routeHelper';
|
||||||
|
|
||||||
import LoginRoute from './modules/sys';
|
|
||||||
|
|
||||||
import dashboard from './modules/dashboard';
|
import dashboard from './modules/dashboard';
|
||||||
|
|
||||||
// demo
|
// demo
|
||||||
|
|
@ -48,5 +46,14 @@ export const RootRoute: AppRouteRecordRaw = {
|
||||||
children: [],
|
children: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const LoginRoute: AppRouteRecordRaw = {
|
||||||
|
path: '/login',
|
||||||
|
name: 'Login',
|
||||||
|
component: () => import('/@/views/sys/login/Login.vue'),
|
||||||
|
meta: {
|
||||||
|
title: '登录',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
// 基础路由 不用权限
|
// 基础路由 不用权限
|
||||||
export const basicRoutes = [LoginRoute, RootRoute];
|
export const basicRoutes = [LoginRoute, RootRoute];
|
||||||
|
|
|
||||||
|
|
@ -96,5 +96,13 @@ export default {
|
||||||
title: '全屏',
|
title: '全屏',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/testTab/:id',
|
||||||
|
name: 'TestTab',
|
||||||
|
component: () => import('/@/views/demo/feat/tab-params/index.vue'),
|
||||||
|
meta: {
|
||||||
|
title: 'Tab带参',
|
||||||
|
},
|
||||||
|
},
|
||||||
],
|
],
|
||||||
} as AppRouteModule;
|
} as AppRouteModule;
|
||||||
|
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
import type { AppRouteRecordRaw } from '/@/router/types';
|
|
||||||
|
|
||||||
const routes: AppRouteRecordRaw = {
|
|
||||||
path: '/login',
|
|
||||||
name: 'Login',
|
|
||||||
component: () => import('/@/views/sys/login/Login.vue'),
|
|
||||||
meta: {
|
|
||||||
title: '登录',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export default routes;
|
|
||||||
|
|
@ -39,6 +39,7 @@ export interface AppRouteRecordRaw extends Omit<RouteRecordRaw, 'meta'> {
|
||||||
components?: any;
|
components?: any;
|
||||||
children?: AppRouteRecordRaw[];
|
children?: AppRouteRecordRaw[];
|
||||||
props?: any;
|
props?: any;
|
||||||
|
fullPath?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Menu {
|
export interface Menu {
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import { appStore } from '/@/store/modules/app';
|
||||||
import store from '/@/store';
|
import store from '/@/store';
|
||||||
import router from '/@/router';
|
import router from '/@/router';
|
||||||
import { PAGE_NOT_FOUND_ROUTE, REDIRECT_ROUTE } from '/@/router/constant';
|
import { PAGE_NOT_FOUND_ROUTE, REDIRECT_ROUTE } from '/@/router/constant';
|
||||||
|
import { getCurrentTo } from '/@/utils/helper/routeHelper';
|
||||||
|
|
||||||
type CacheName = string | symbol | null | undefined;
|
type CacheName = string | symbol | null | undefined;
|
||||||
/**
|
/**
|
||||||
|
|
@ -18,7 +19,10 @@ type CacheName = string | symbol | null | undefined;
|
||||||
*/
|
*/
|
||||||
// declare namespace TabsStore {
|
// declare namespace TabsStore {
|
||||||
export interface TabItem {
|
export interface TabItem {
|
||||||
path: string;
|
fullPath: string;
|
||||||
|
path?: string;
|
||||||
|
params?: any;
|
||||||
|
query?: any;
|
||||||
name?: CacheName;
|
name?: CacheName;
|
||||||
meta?: RouteMeta;
|
meta?: RouteMeta;
|
||||||
}
|
}
|
||||||
|
|
@ -86,20 +90,21 @@ class Tab extends VuexModule {
|
||||||
*/
|
*/
|
||||||
@Mutation
|
@Mutation
|
||||||
commitAddTab(route: AppRouteRecordRaw | TabItem): void {
|
commitAddTab(route: AppRouteRecordRaw | TabItem): void {
|
||||||
const { path, name, meta } = route;
|
const { path, name, meta, fullPath, params, query } = route as TabItem;
|
||||||
// 404 页面不需要添加tab
|
// 404 页面不需要添加tab
|
||||||
if (path === PageEnum.ERROR_PAGE) {
|
if (path === PageEnum.ERROR_PAGE) {
|
||||||
return;
|
return;
|
||||||
} else if ([REDIRECT_ROUTE.name, PAGE_NOT_FOUND_ROUTE.name].includes(name as string)) {
|
} else if ([REDIRECT_ROUTE.name, PAGE_NOT_FOUND_ROUTE.name].includes(name as string)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 已经存在的页面,不重复添加tab
|
// 已经存在的页面,不重复添加tab
|
||||||
const hasTab = this.tabsState.some((tab) => {
|
const hasTab = this.tabsState.some((tab) => {
|
||||||
return tab.path === path;
|
return tab.fullPath === fullPath;
|
||||||
});
|
});
|
||||||
if (hasTab) return;
|
if (hasTab) return;
|
||||||
|
|
||||||
this.tabsState.push({ path, name, meta });
|
this.tabsState.push({ path, fullPath, name, meta, params, query });
|
||||||
if (unref(getOpenKeepAliveRef) && name) {
|
if (unref(getOpenKeepAliveRef) && name) {
|
||||||
const noKeepAlive = meta && meta.ignoreKeepAlive;
|
const noKeepAlive = meta && meta.ignoreKeepAlive;
|
||||||
const hasName = this.keepAliveTabsState.includes(name);
|
const hasName = this.keepAliveTabsState.includes(name);
|
||||||
|
|
@ -113,9 +118,9 @@ class Tab extends VuexModule {
|
||||||
@Mutation
|
@Mutation
|
||||||
commitCloseTab(route: AppRouteRecordRaw | TabItem): void {
|
commitCloseTab(route: AppRouteRecordRaw | TabItem): void {
|
||||||
try {
|
try {
|
||||||
const { path, name, meta: { affix } = {} } = route;
|
const { fullPath, name, meta: { affix } = {} } = route;
|
||||||
if (affix) return;
|
if (affix) return;
|
||||||
const index = this.tabsState.findIndex((item) => item.path === path);
|
const index = this.tabsState.findIndex((item) => item.fullPath === fullPath);
|
||||||
index !== -1 && this.tabsState.splice(index, 1);
|
index !== -1 && this.tabsState.splice(index, 1);
|
||||||
|
|
||||||
if (unref(getOpenKeepAliveRef) && name) {
|
if (unref(getOpenKeepAliveRef) && name) {
|
||||||
|
|
@ -153,7 +158,7 @@ class Tab extends VuexModule {
|
||||||
|
|
||||||
@Mutation
|
@Mutation
|
||||||
closeMultipleTab({ pathList, nameList }: { pathList: string[]; nameList: string[] }): void {
|
closeMultipleTab({ pathList, nameList }: { pathList: string[]; nameList: string[] }): void {
|
||||||
this.tabsState = toRaw(this.tabsState).filter((item) => !pathList.includes(item.path));
|
this.tabsState = toRaw(this.tabsState).filter((item) => !pathList.includes(item.fullPath));
|
||||||
if (unref(getOpenKeepAliveRef) && nameList) {
|
if (unref(getOpenKeepAliveRef) && nameList) {
|
||||||
this.keepAliveTabsState = toRaw(this.keepAliveTabsState).filter(
|
this.keepAliveTabsState = toRaw(this.keepAliveTabsState).filter(
|
||||||
(item) => !nameList.includes(item as string)
|
(item) => !nameList.includes(item as string)
|
||||||
|
|
@ -172,7 +177,7 @@ class Tab extends VuexModule {
|
||||||
for (const item of leftTabs) {
|
for (const item of leftTabs) {
|
||||||
const affix = item.meta ? item.meta.affix : false;
|
const affix = item.meta ? item.meta.affix : false;
|
||||||
if (!affix) {
|
if (!affix) {
|
||||||
pathList.push(item.path);
|
pathList.push(item.fullPath);
|
||||||
nameList.push(item.name as string);
|
nameList.push(item.name as string);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -181,13 +186,19 @@ class Tab extends VuexModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Action
|
@Action
|
||||||
addTabByPathAction(to: AppRouteRecordRaw): void {
|
addTabByPathAction(): void {
|
||||||
to && this.commitAddTab((to as unknown) as AppRouteRecordRaw);
|
const toRoute = getCurrentTo();
|
||||||
|
if (!toRoute) return;
|
||||||
|
const { meta } = toRoute;
|
||||||
|
if (meta && meta.affix) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.commitAddTab((toRoute as unknown) as AppRouteRecordRaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Action
|
@Action
|
||||||
closeRightTabAction(route: AppRouteRecordRaw | TabItem): void {
|
closeRightTabAction(route: AppRouteRecordRaw | TabItem): void {
|
||||||
const index = this.tabsState.findIndex((item) => item.path === route.path);
|
const index = this.tabsState.findIndex((item) => item.fullPath === route.fullPath);
|
||||||
|
|
||||||
if (index >= 0 && index < this.tabsState.length - 1) {
|
if (index >= 0 && index < this.tabsState.length - 1) {
|
||||||
const rightTabs = this.tabsState.slice(index + 1, this.tabsState.length);
|
const rightTabs = this.tabsState.slice(index + 1, this.tabsState.length);
|
||||||
|
|
@ -197,7 +208,7 @@ class Tab extends VuexModule {
|
||||||
for (const item of rightTabs) {
|
for (const item of rightTabs) {
|
||||||
const affix = item.meta ? item.meta.affix : false;
|
const affix = item.meta ? item.meta.affix : false;
|
||||||
if (!affix) {
|
if (!affix) {
|
||||||
pathList.push(item.path);
|
pathList.push(item.fullPath);
|
||||||
nameList.push(item.name as string);
|
nameList.push(item.name as string);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -207,16 +218,16 @@ class Tab extends VuexModule {
|
||||||
|
|
||||||
@Action
|
@Action
|
||||||
closeOtherTabAction(route: AppRouteRecordRaw | TabItem): void {
|
closeOtherTabAction(route: AppRouteRecordRaw | TabItem): void {
|
||||||
const closePathList = this.tabsState.map((item) => item.path);
|
const closePathList = this.tabsState.map((item) => item.fullPath);
|
||||||
const pathList: string[] = [];
|
const pathList: string[] = [];
|
||||||
const nameList: string[] = [];
|
const nameList: string[] = [];
|
||||||
closePathList.forEach((path) => {
|
closePathList.forEach((path) => {
|
||||||
if (path !== route.path) {
|
if (path !== route.fullPath) {
|
||||||
const closeItem = this.tabsState.find((item) => item.path === path);
|
const closeItem = this.tabsState.find((item) => item.path === path);
|
||||||
if (!closeItem) return;
|
if (!closeItem) return;
|
||||||
const affix = closeItem.meta ? closeItem.meta.affix : false;
|
const affix = closeItem.meta ? closeItem.meta.affix : false;
|
||||||
if (!affix) {
|
if (!affix) {
|
||||||
pathList.push(closeItem.path);
|
pathList.push(closeItem.fullPath);
|
||||||
nameList.push(closeItem.name as string);
|
nameList.push(closeItem.name as string);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
declare module 'ant-design-vue/es/locale/zh_CN';
|
declare module 'ant-design-vue/es/locale/zh_CN';
|
||||||
declare module 'vue-draggable-resizable';
|
declare module 'globby!/@/router/routes/modules/**/*.@(ts)';
|
||||||
|
declare module 'globby!/@/router/menus/modules/**/*.@(ts)';
|
||||||
|
|
||||||
declare const React: string;
|
declare const React: string;
|
||||||
declare module '*.bmp' {
|
declare module '*.bmp' {
|
||||||
const src: string;
|
const src: string;
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,6 @@ class EventHub {
|
||||||
|
|
||||||
emit(eventName: string, data?: any) {
|
emit(eventName: string, data?: any) {
|
||||||
if (this.cache[eventName] === undefined) return;
|
if (this.cache[eventName] === undefined) return;
|
||||||
console.log('======================');
|
|
||||||
console.log(this.cache, eventName);
|
|
||||||
console.log('======================');
|
|
||||||
this.cache[eventName].forEach((fn) => fn(data));
|
this.cache[eventName].forEach((fn) => fn(data));
|
||||||
}
|
}
|
||||||
off(eventName: string, fn: (data: any) => void) {
|
off(eventName: string, fn: (data: any) => void) {
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import type { MenuModule, Menu, AppRouteRecordRaw } from '/@/router/types';
|
||||||
import { findPath, forEach, treeMap, treeToList } from './treeHelper';
|
import { findPath, forEach, treeMap, treeToList } from './treeHelper';
|
||||||
import { cloneDeep } from 'lodash-es';
|
import { cloneDeep } from 'lodash-es';
|
||||||
|
|
||||||
//
|
|
||||||
export function getAllParentPath(treeData: any[], path: string) {
|
export function getAllParentPath(treeData: any[], path: string) {
|
||||||
const menuList = findPath(treeData, (n) => n.path === path) as Menu[];
|
const menuList = findPath(treeData, (n) => n.path === path) as Menu[];
|
||||||
return (menuList || []).map((item) => item.path);
|
return (menuList || []).map((item) => item.path);
|
||||||
|
|
@ -14,6 +13,7 @@ export function flatMenus(menus: Menu[]) {
|
||||||
return treeToList(menus);
|
return treeToList(menus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 拼接父级路径
|
||||||
function joinParentPath(list: any, node: any) {
|
function joinParentPath(list: any, node: any) {
|
||||||
let allPaths = getAllParentPath(list, node.path);
|
let allPaths = getAllParentPath(list, node.path);
|
||||||
|
|
||||||
|
|
@ -26,7 +26,6 @@ function joinParentPath(list: any, node: any) {
|
||||||
parentPath += /^\//.test(p) ? p : `/${p}`;
|
parentPath += /^\//.test(p) ? p : `/${p}`;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
node.path = `${parentPath}${/^\//.test(node.path) ? node.path : `/${node.path}`}`.replace(
|
node.path = `${parentPath}${/^\//.test(node.path) ? node.path : `/${node.path}`}`.replace(
|
||||||
/\/\//g,
|
/\/\//g,
|
||||||
'/'
|
'/'
|
||||||
|
|
@ -34,6 +33,7 @@ function joinParentPath(list: any, node: any) {
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 解析菜单模块
|
||||||
export function transformMenuModule(menuModule: MenuModule): Menu {
|
export function transformMenuModule(menuModule: MenuModule): Menu {
|
||||||
const { menu } = menuModule;
|
const { menu } = menuModule;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,23 @@
|
||||||
import type { AppRouteModule, AppRouteRecordRaw } from '/@/router/types';
|
import type { AppRouteModule, AppRouteRecordRaw } from '/@/router/types';
|
||||||
import type { RouteRecordRaw } from 'vue-router';
|
import type { RouteLocationNormalized, RouteRecordRaw } from 'vue-router';
|
||||||
|
|
||||||
import { appStore } from '/@/store/modules/app';
|
import { appStore } from '/@/store/modules/app';
|
||||||
import { tabStore } from '/@/store/modules/tab';
|
import { tabStore } from '/@/store/modules/tab';
|
||||||
import { createRouter, createWebHashHistory } from 'vue-router';
|
import { createRouter, createWebHashHistory } from 'vue-router';
|
||||||
import { toRaw } from 'vue';
|
import { toRaw } from 'vue';
|
||||||
import { PAGE_LAYOUT_COMPONENT } from '/@/router/constant';
|
import { PAGE_LAYOUT_COMPONENT } from '/@/router/constant';
|
||||||
|
|
||||||
|
let currentTo: RouteLocationNormalized | null = null;
|
||||||
|
|
||||||
|
export function getCurrentTo() {
|
||||||
|
return currentTo;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setCurrentTo(to: RouteLocationNormalized) {
|
||||||
|
currentTo = to;
|
||||||
|
}
|
||||||
|
// 转化路由模块
|
||||||
|
// 将多级转成2层。keepAlive问题
|
||||||
export function genRouteModule(moduleList: AppRouteModule[]) {
|
export function genRouteModule(moduleList: AppRouteModule[]) {
|
||||||
const ret: AppRouteRecordRaw[] = [];
|
const ret: AppRouteRecordRaw[] = [];
|
||||||
for (const routeMod of moduleList) {
|
for (const routeMod of moduleList) {
|
||||||
|
|
@ -27,6 +39,7 @@ export function genRouteModule(moduleList: AppRouteModule[]) {
|
||||||
return ret as RouteRecordRaw[];
|
return ret as RouteRecordRaw[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 动态引入
|
||||||
function asyncImportRoute(routes: AppRouteRecordRaw[]) {
|
function asyncImportRoute(routes: AppRouteRecordRaw[]) {
|
||||||
routes.forEach((item) => {
|
routes.forEach((item) => {
|
||||||
const { component, children } = item;
|
const { component, children } = item;
|
||||||
|
|
@ -37,6 +50,7 @@ function asyncImportRoute(routes: AppRouteRecordRaw[]) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 将后台对象转成路由对象
|
||||||
export function transformObjToRoute(routeList: AppRouteModule[]) {
|
export function transformObjToRoute(routeList: AppRouteModule[]) {
|
||||||
routeList.forEach((route) => {
|
routeList.forEach((route) => {
|
||||||
asyncImportRoute(route.routes);
|
asyncImportRoute(route.routes);
|
||||||
|
|
@ -48,6 +62,7 @@ export function transformObjToRoute(routeList: AppRouteModule[]) {
|
||||||
return routeList;
|
return routeList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
export function getIsOpenTab(toPath: string) {
|
export function getIsOpenTab(toPath: string) {
|
||||||
const { openKeepAlive, multiTabsSetting: { show } = {} } = appStore.getProjectConfig;
|
const { openKeepAlive, multiTabsSetting: { show } = {} } = appStore.getProjectConfig;
|
||||||
|
|
||||||
|
|
@ -57,3 +72,13 @@ export function getIsOpenTab(toPath: string) {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getParams(data: any = {}) {
|
||||||
|
const { params = {} } = data;
|
||||||
|
let ret = '';
|
||||||
|
Object.keys(params).forEach((key) => {
|
||||||
|
const p = params[key];
|
||||||
|
ret += `/${p}`;
|
||||||
|
});
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
<template>
|
||||||
|
<div class="p-4"> Current Param : {{ params }} </div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts">
|
||||||
|
import { computed, defineComponent, unref } from 'vue';
|
||||||
|
import { useRouter } from 'vue-router';
|
||||||
|
export default defineComponent({
|
||||||
|
setup() {
|
||||||
|
const { currentRoute } = useRouter();
|
||||||
|
return {
|
||||||
|
params: computed(() => {
|
||||||
|
return unref(currentRoute).params;
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
<div />
|
<div />
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, onBeforeMount, unref } from 'vue';
|
import { defineComponent, unref } from 'vue';
|
||||||
|
|
||||||
import { appStore } from '/@/store/modules/app';
|
import { appStore } from '/@/store/modules/app';
|
||||||
|
|
||||||
|
|
@ -11,21 +11,19 @@
|
||||||
name: 'Redirect',
|
name: 'Redirect',
|
||||||
setup() {
|
setup() {
|
||||||
const { currentRoute, replace } = useRouter();
|
const { currentRoute, replace } = useRouter();
|
||||||
onBeforeMount(() => {
|
const { params, query } = unref(currentRoute);
|
||||||
const { params, query } = unref(currentRoute);
|
const { path } = params;
|
||||||
const { path } = params;
|
const _path = Array.isArray(path) ? path.join('/') : path;
|
||||||
const _path = Array.isArray(path) ? path.join('/') : path;
|
replace({
|
||||||
replace({
|
path: '/' + _path,
|
||||||
path: '/' + _path,
|
query,
|
||||||
query,
|
|
||||||
});
|
|
||||||
const { openRouterTransition, openPageLoading } = appStore.getProjectConfig;
|
|
||||||
if (openRouterTransition && openPageLoading) {
|
|
||||||
setTimeout(() => {
|
|
||||||
appStore.setPageLoadingAction(false);
|
|
||||||
}, 0);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
const { openRouterTransition, openPageLoading } = appStore.getProjectConfig;
|
||||||
|
if (openRouterTransition && openPageLoading) {
|
||||||
|
setTimeout(() => {
|
||||||
|
appStore.setPageLoadingAction(false);
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
return {};
|
return {};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ const viteConfig: UserConfig = {
|
||||||
* boolean | 'terser' | 'esbuild'
|
* boolean | 'terser' | 'esbuild'
|
||||||
* @default 'terser'
|
* @default 'terser'
|
||||||
*/
|
*/
|
||||||
minify: isDevFn() ? false : 'terser',
|
minify: 'terser',
|
||||||
/**
|
/**
|
||||||
* 基本公共路径
|
* 基本公共路径
|
||||||
* @default '/'
|
* @default '/'
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue