From e35fa8b90e885b7e14e83f008e7cb09cc602bf89 Mon Sep 17 00:00:00 2001 From: yuntian001 <479820787@qq.com> Date: Fri, 19 Aug 2022 17:00:01 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=8A=A0=E4=B8=8A=E8=AF=B7=E6=B1=82?= =?UTF-8?q?=E7=A4=BA=E4=BE=8B=EF=BC=8C=E4=BF=AE=E5=A4=8D=E8=BF=9B=E5=BA=A6?= =?UTF-8?q?=E6=9D=A1bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mock/apiDemo/example.ts | 31 +++++++++++++++++++++ plugin/vueSetupExtend.ts | 11 ++++---- src/App.vue | 2 +- src/api/example.ts | 30 +++++++++++++++++++++ src/api/user.ts | 12 ++++----- src/components/meComponent.vue | 5 ++-- src/enums/pageEnum.ts | 2 +- src/layout/components/page.vue | 16 +++-------- src/layout/index.vue | 7 ++++- src/router/guard/index.ts | 8 +++--- src/router/routes/example/3-request.ts | 8 ++++++ src/router/routes/example/4-link.ts | 8 ++++++ src/router/routes/example/5-multilevel.ts | 13 +++++++++ src/router/routes/example/multilevel/1.ts | 33 +++++++++++++++++++++++ src/store/modules/user.ts | 1 - src/utils/nProgress.ts | 26 ++++++++++++++++++ src/utils/request.ts | 4 +-- src/views/example/request.vue | 28 +++++++++++++++++++ src/views/link.vue | 11 -------- types/vue-router.d.ts | 2 +- 20 files changed, 210 insertions(+), 48 deletions(-) create mode 100644 mock/apiDemo/example.ts create mode 100644 src/api/example.ts create mode 100644 src/router/routes/example/3-request.ts create mode 100644 src/router/routes/example/4-link.ts create mode 100644 src/router/routes/example/5-multilevel.ts create mode 100644 src/router/routes/example/multilevel/1.ts create mode 100644 src/utils/nProgress.ts create mode 100644 src/views/example/request.vue delete mode 100644 src/views/link.vue diff --git a/mock/apiDemo/example.ts b/mock/apiDemo/example.ts new file mode 100644 index 00000000..2a44b8fa --- /dev/null +++ b/mock/apiDemo/example.ts @@ -0,0 +1,31 @@ +import { success, fail } from '../helper'; + +export default [ + { + url: '/api/list', // + method: 'get', + response: (req: { body: { username: any }; query: { page?: number; size?: number } }) => { + const query = req.query; + if (!query.page || !query.size) { + return fail('page和size必填'); + } + if (query.page < 1) { + return fail('page必须大于0'); + } + if (query.size < 1) { + return fail('size必须大于0'); + } + const list = [] as string[]; + for (let i = 0; i < query.size; i++) { + list.push(`item-${query.page}-${i}`); + } + return success( + { + total: 30, + list, + }, + '登录成功', + ); + }, + }, +]; diff --git a/plugin/vueSetupExtend.ts b/plugin/vueSetupExtend.ts index e8dad3e6..3528679c 100644 --- a/plugin/vueSetupExtend.ts +++ b/plugin/vueSetupExtend.ts @@ -21,12 +21,14 @@ function getLangImport(content: string) { if (useI18nParams) { useI18nParams = useI18nParams.replace(/(\s*$)/g, ''); } + if (useI18nParams.endsWith(']')) { const arr = xregexp.matchRecursive(useI18nParams, '\\[', '\\]', 'g', { escapeChar: '\\', valueNames: [null, null, 'value', null], }); const res = arr[arr.length - 1]; + if (res && /,\s*$/.test(useI18nParams.slice(0, res.start - 1))) { return '[' + res.value + ']'; } @@ -66,7 +68,7 @@ function getComponent(sfc: SFCDescriptor) { } export function supportScript(code: string, options: ExtendOptions) { - const str = () => new MagicString(code); + const str = new MagicString(code); const { descriptor } = parse(code); if (!descriptor.script && descriptor.scriptSetup) { const attrs = { ...descriptor.scriptSetup.attrs }; @@ -97,9 +99,8 @@ export function supportScript(code: string, options: ExtendOptions) { scriptStr += `"${k}":"${attrs[k]}",`; } } - if (scriptStr) { - str().appendLeft( + str.appendLeft( 0, ` - diff --git a/src/layout/index.vue b/src/layout/index.vue index b6a3f12d..bd190a6a 100644 --- a/src/layout/index.vue +++ b/src/layout/index.vue @@ -10,7 +10,9 @@ - +
+ +
@@ -57,6 +59,9 @@ const globalStore = useGlobalStore(); } } +.main { + padding: 1rem; +} :global(.me-sidebar-drawer .el-drawer__body) { padding: 0; } diff --git a/src/router/guard/index.ts b/src/router/guard/index.ts index 15e45d70..9a3bcb3f 100644 --- a/src/router/guard/index.ts +++ b/src/router/guard/index.ts @@ -2,7 +2,7 @@ import type { NavigationFailure, Router } from 'vue-router'; import { PageEnum } from '@/enums/pageEnum'; import { useUserStore } from '@/store'; import { event, mitter } from '@/event'; -import nProgress from 'nprogress'; +import { start } from '@/utils/nProgress'; // Don't change the order of creation export function setupRouterGuard(router: Router) { createPermissionGuard(router); @@ -18,7 +18,7 @@ function createPermissionGuard(router: Router) { const userStore = useUserStore(); router.beforeEach(async (to) => { if (to.path !== PageEnum.LOGIN && !userStore.token) { - await router.replace(PageEnum.LOGIN); + await router.replace({ path: PageEnum.LOGIN, query: { redirect: to.fullPath } }); return false; } else if (to.path === PageEnum.LOGIN && userStore.token) { await router.replace(PageEnum.HOME); @@ -29,8 +29,8 @@ function createPermissionGuard(router: Router) { // 处理页面加载进度条 function createProgressGuard(router: Router) { - router.beforeEach(async () => { - nProgress.start(); + router.beforeEach(async (to) => { + start(to.matched.length); return true; }); } diff --git a/src/router/routes/example/3-request.ts b/src/router/routes/example/3-request.ts new file mode 100644 index 00000000..f19c7bf6 --- /dev/null +++ b/src/router/routes/example/3-request.ts @@ -0,0 +1,8 @@ +import { RouteRecordRaw } from 'vue-router'; +export const routes: RouteRecordRaw[] = [ + { + path: 'request', + component: async () => await import('@/views/example/request.vue'), + meta: { title: '请求示例' }, + }, +]; diff --git a/src/router/routes/example/4-link.ts b/src/router/routes/example/4-link.ts new file mode 100644 index 00000000..0311b93b --- /dev/null +++ b/src/router/routes/example/4-link.ts @@ -0,0 +1,8 @@ +import { RouteRecordRaw } from 'vue-router'; +export const routes: RouteRecordRaw[] = [ + { + path: 'https://github.com/meadmin-cn/meadmin-template', + component: async () => await import('@/views/404.vue'), + meta: { title: '外链', isLink: true }, + }, +]; diff --git a/src/router/routes/example/5-multilevel.ts b/src/router/routes/example/5-multilevel.ts new file mode 100644 index 00000000..0d187918 --- /dev/null +++ b/src/router/routes/example/5-multilevel.ts @@ -0,0 +1,13 @@ +import { RouteRecordRaw, RouterView } from 'vue-router'; +import LayoutPage from '@/layout/components/page.vue'; +import { concatObjectValue } from '@/utils/helper'; +export const routes: RouteRecordRaw[] = [ + { + path: 'multilevel', + component: LayoutPage, + meta: { title: '多级菜单' }, + children: concatObjectValue( + import.meta.glob('./multilevel/*.ts', { eager: true, import: 'routes' }), + ), + }, +]; diff --git a/src/router/routes/example/multilevel/1.ts b/src/router/routes/example/multilevel/1.ts new file mode 100644 index 00000000..01645e7c --- /dev/null +++ b/src/router/routes/example/multilevel/1.ts @@ -0,0 +1,33 @@ +import { RouteRecordRaw, RouterView } from 'vue-router'; +import LayoutPage from '@/layout/components/page.vue'; +export const routes: RouteRecordRaw[] = [ + { + path: '1', + component: LayoutPage, + meta: { title: '多级菜单1' }, + children: [ + { + path: '1-1', + component: LayoutPage, + meta: { title: '多级菜单1-1', alwaysShow: true }, + children: [ + { + path: '1-1-1', + component: () => import('@/views/dashboard/index.vue'), + meta: { title: '多级菜单1-1-1' }, + }, + { + path: '/test/componentLang', + component: async () => await import('@/views/example/componentLang/index.vue'), + meta: { title: '组件语言包' }, + }, + ], + }, + { + path: '1-2', + component: () => import('@/views/dashboard/index.vue'), + meta: { title: '多级菜单1-2' }, + }, + ], + }, +]; diff --git a/src/store/modules/user.ts b/src/store/modules/user.ts index 26181bb8..870733bd 100644 --- a/src/store/modules/user.ts +++ b/src/store/modules/user.ts @@ -73,7 +73,6 @@ export default defineStore({ this.token = ''; await router.replace({ path: PageEnum.LOGIN, - query: { redirect: window.location.href }, }); window.location.reload(); }, diff --git a/src/utils/nProgress.ts b/src/utils/nProgress.ts new file mode 100644 index 00000000..830b812b --- /dev/null +++ b/src/utils/nProgress.ts @@ -0,0 +1,26 @@ +import nProgress from 'nprogress'; +let number = 0; +export const done = (n = 1) => { + number -= n; + if (number <= 0) { + nProgress.done(); + number = 0; + } else { + nProgress.set(number / (number + n)); + } +}; + +export const start = (n = 1) => { + if (number <= 0) { + nProgress.start(); + number = n; + } else { + number += n; + } +}; + +export const set = (n: number) => { + if (number > 0) { + nProgress.set(n); + } +}; diff --git a/src/utils/request.ts b/src/utils/request.ts index d5acca5b..b8da07b7 100644 --- a/src/utils/request.ts +++ b/src/utils/request.ts @@ -79,7 +79,7 @@ function request( !options?.noLoading && loading(); const { data: res } = await service(await axiosConfig(...args)); if (!res || res.code === undefined) { - throw Error('格式错误'); + throw Error('返回值解析失败'); } // 401:认证失败 if (res.code === '401') { @@ -87,7 +87,7 @@ function request( return res; } if (res.code !== '200') { - throw res.msg; + throw Error(res.msg); } !options?.noLoading && closeLoading(); diff --git a/src/views/example/request.vue b/src/views/example/request.vue new file mode 100644 index 00000000..b316785c --- /dev/null +++ b/src/views/example/request.vue @@ -0,0 +1,28 @@ + + diff --git a/src/views/link.vue b/src/views/link.vue deleted file mode 100644 index 1335f4f0..00000000 --- a/src/views/link.vue +++ /dev/null @@ -1,11 +0,0 @@ - - - diff --git a/types/vue-router.d.ts b/types/vue-router.d.ts index 66cd186d..b9f97ec2 100644 --- a/types/vue-router.d.ts +++ b/types/vue-router.d.ts @@ -16,7 +16,7 @@ declare module 'vue-router' { // 当路由设置了该属性,则会高亮相对应的侧边栏。 // 这在某些场景非常有用,比如:一个文章的列表页路由为:/article/list // 点击文章进入文章详情页,这时候路由为/article/1,但你想在侧边栏高亮文章列表的路由,就可以进行如下设置 - // 如果不设置会自动计算展示不隐藏的祖级(包括当前) + // asyncRoutes如果不设置会自动计算展示不隐藏的祖级(包括当前) activeMenu?: string; // 如果设置为true,则不会被 缓存 noCache?: boolean;