refactor(router): 优化路由认证检查逻辑
重构路由认证检查逻辑,使用更灵活的正则和精确匹配模式,提高代码可维护性
Showing
1 changed file
with
49 additions
and
30 deletions
| 1 | /* | 1 | /* |
| 2 | * @Date: 2025-03-20 20:36:36 | 2 | * @Date: 2025-03-20 20:36:36 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2025-03-21 15:59:36 | 4 | + * @LastEditTime: 2025-03-21 17:58:10 |
| 5 | * @FilePath: /mlaj/src/router/index.js | 5 | * @FilePath: /mlaj/src/router/index.js |
| 6 | * @Description: 文件描述 | 6 | * @Description: 文件描述 |
| 7 | */ | 7 | */ |
| ... | @@ -31,13 +31,13 @@ const routes = [ | ... | @@ -31,13 +31,13 @@ const routes = [ |
| 31 | path: '/courses/:id/reviews', | 31 | path: '/courses/:id/reviews', |
| 32 | name: 'CourseReviews', | 32 | name: 'CourseReviews', |
| 33 | component: () => import('../views/courses/CourseReviewsPage.vue'), | 33 | component: () => import('../views/courses/CourseReviewsPage.vue'), |
| 34 | - meta: { title: '课程评价' } | 34 | + meta: { title: '课程评价' }, |
| 35 | }, | 35 | }, |
| 36 | { | 36 | { |
| 37 | path: '/courses-list', | 37 | path: '/courses-list', |
| 38 | name: 'CourseList', | 38 | name: 'CourseList', |
| 39 | component: () => import('../views/courses/CourseListPage.vue'), | 39 | component: () => import('../views/courses/CourseListPage.vue'), |
| 40 | - meta: { title: '课程列表' } | 40 | + meta: { title: '课程列表' }, |
| 41 | }, | 41 | }, |
| 42 | { | 42 | { |
| 43 | path: '/profile', | 43 | path: '/profile', |
| ... | @@ -49,79 +49,79 @@ const routes = [ | ... | @@ -49,79 +49,79 @@ const routes = [ |
| 49 | path: '/login', | 49 | path: '/login', |
| 50 | name: 'Login', | 50 | name: 'Login', |
| 51 | component: () => import('../views/auth/LoginPage.vue'), | 51 | component: () => import('../views/auth/LoginPage.vue'), |
| 52 | - meta: { title: '登录' } | 52 | + meta: { title: '登录' }, |
| 53 | }, | 53 | }, |
| 54 | { | 54 | { |
| 55 | path: '/register', | 55 | path: '/register', |
| 56 | name: 'Register', | 56 | name: 'Register', |
| 57 | component: () => import('../views/auth/RegisterPage.vue'), | 57 | component: () => import('../views/auth/RegisterPage.vue'), |
| 58 | - meta: { title: '注册' } | 58 | + meta: { title: '注册' }, |
| 59 | }, | 59 | }, |
| 60 | { | 60 | { |
| 61 | path: '/forgotPwd', | 61 | path: '/forgotPwd', |
| 62 | name: 'ForgotPassword', | 62 | name: 'ForgotPassword', |
| 63 | component: () => import('../views/auth/ForgotPasswordPage.vue'), | 63 | component: () => import('../views/auth/ForgotPasswordPage.vue'), |
| 64 | - meta: { title: '忘记密码' } | 64 | + meta: { title: '忘记密码' }, |
| 65 | }, | 65 | }, |
| 66 | { | 66 | { |
| 67 | path: '/activities', | 67 | path: '/activities', |
| 68 | name: 'Activities', | 68 | name: 'Activities', |
| 69 | component: () => import('../views/activities/ActivitiesPage.vue'), | 69 | component: () => import('../views/activities/ActivitiesPage.vue'), |
| 70 | - meta: { title: '活动列表' } | 70 | + meta: { title: '活动列表' }, |
| 71 | }, | 71 | }, |
| 72 | { | 72 | { |
| 73 | path: '/activities/:id', | 73 | path: '/activities/:id', |
| 74 | name: 'ActivityDetail', | 74 | name: 'ActivityDetail', |
| 75 | component: () => import('../views/activities/ActivityDetailPage.vue'), | 75 | component: () => import('../views/activities/ActivityDetailPage.vue'), |
| 76 | props: true, | 76 | props: true, |
| 77 | - meta: { title: '活动详情' } | 77 | + meta: { title: '活动详情' }, |
| 78 | }, | 78 | }, |
| 79 | { | 79 | { |
| 80 | path: '/activities/:id/signup', | 80 | path: '/activities/:id/signup', |
| 81 | name: 'ActivitySignup', | 81 | name: 'ActivitySignup', |
| 82 | component: () => import('../views/activities/ActivitySignupPage.vue'), | 82 | component: () => import('../views/activities/ActivitySignupPage.vue'), |
| 83 | meta: { | 83 | meta: { |
| 84 | - title: '活动报名' | 84 | + title: '活动报名', |
| 85 | - } | 85 | + }, |
| 86 | }, | 86 | }, |
| 87 | { | 87 | { |
| 88 | path: '/profile/activities', | 88 | path: '/profile/activities', |
| 89 | name: 'MyActivities', | 89 | name: 'MyActivities', |
| 90 | component: () => import('../views/activities/MyActivitiesPage.vue'), | 90 | component: () => import('../views/activities/MyActivitiesPage.vue'), |
| 91 | - meta: { title: '我的活动' } | 91 | + meta: { title: '我的活动' }, |
| 92 | }, | 92 | }, |
| 93 | { | 93 | { |
| 94 | path: '/checkout', | 94 | path: '/checkout', |
| 95 | name: 'CheckoutPage', | 95 | name: 'CheckoutPage', |
| 96 | component: () => import('../views/checkout/CheckoutPage.vue'), | 96 | component: () => import('../views/checkout/CheckoutPage.vue'), |
| 97 | props: true, | 97 | props: true, |
| 98 | - meta: { title: '结账' } | 98 | + meta: { title: '结账' }, |
| 99 | }, | 99 | }, |
| 100 | { | 100 | { |
| 101 | path: '/profile/courses', | 101 | path: '/profile/courses', |
| 102 | name: 'MyCourses', | 102 | name: 'MyCourses', |
| 103 | component: () => import('../views/courses/MyCoursesPage.vue'), | 103 | component: () => import('../views/courses/MyCoursesPage.vue'), |
| 104 | - meta: { title: '我的课程' } | 104 | + meta: { title: '我的课程' }, |
| 105 | }, | 105 | }, |
| 106 | { | 106 | { |
| 107 | path: '/profile/orders', | 107 | path: '/profile/orders', |
| 108 | name: 'Orders', | 108 | name: 'Orders', |
| 109 | component: () => import('../views/profile/OrdersPage.vue'), | 109 | component: () => import('../views/profile/OrdersPage.vue'), |
| 110 | - meta: { title: '我的订单' } | 110 | + meta: { title: '我的订单' }, |
| 111 | }, | 111 | }, |
| 112 | { | 112 | { |
| 113 | path: '/profile/favorites', | 113 | path: '/profile/favorites', |
| 114 | name: 'MyFavorites', | 114 | name: 'MyFavorites', |
| 115 | component: () => import('../views/profile/MyFavoritesPage.vue'), | 115 | component: () => import('../views/profile/MyFavoritesPage.vue'), |
| 116 | - meta: { title: '我的收藏' } | 116 | + meta: { title: '我的收藏' }, |
| 117 | }, | 117 | }, |
| 118 | { | 118 | { |
| 119 | path: '/test', | 119 | path: '/test', |
| 120 | name: 'test', | 120 | name: 'test', |
| 121 | component: () => import('../views/test.vue'), | 121 | component: () => import('../views/test.vue'), |
| 122 | - meta: { title: 'test' } | 122 | + meta: { title: 'test' }, |
| 123 | }, | 123 | }, |
| 124 | - ...checkinRoutes | 124 | + ...checkinRoutes, |
| 125 | ] | 125 | ] |
| 126 | 126 | ||
| 127 | const router = createRouter({ | 127 | const router = createRouter({ |
| ... | @@ -130,30 +130,49 @@ const router = createRouter({ | ... | @@ -130,30 +130,49 @@ const router = createRouter({ |
| 130 | scrollBehavior(to, from, savedPosition) { | 130 | scrollBehavior(to, from, savedPosition) { |
| 131 | // 每次路由切换后,页面滚动到顶部 | 131 | // 每次路由切换后,页面滚动到顶部 |
| 132 | return savedPosition || { top: 0, left: 0 } | 132 | return savedPosition || { top: 0, left: 0 } |
| 133 | - } | 133 | + }, |
| 134 | }) | 134 | }) |
| 135 | 135 | ||
| 136 | // 需要登录才能访问的路由 | 136 | // 需要登录才能访问的路由 |
| 137 | const authRequiredRoutes = [ | 137 | const authRequiredRoutes = [ |
| 138 | - '/profile', | 138 | + { |
| 139 | - '/profile/activities', | 139 | + path: '/profile', |
| 140 | - '/profile/courses', | 140 | + exact: false, |
| 141 | - '/profile/orders', | 141 | + }, |
| 142 | - '/profile/favorites', | 142 | + { |
| 143 | - '/checkout' | 143 | + path: '/checkout', |
| 144 | + exact: true, | ||
| 145 | + }, | ||
| 146 | + { | ||
| 147 | + path: '/activities/[^/]+/signup', | ||
| 148 | + regex: true, | ||
| 149 | + }, | ||
| 144 | ] | 150 | ] |
| 145 | 151 | ||
| 146 | // 导航守卫 | 152 | // 导航守卫 |
| 147 | router.beforeEach((to, from, next) => { | 153 | router.beforeEach((to, from, next) => { |
| 148 | const currentUser = JSON.parse(localStorage.getItem('currentUser')) | 154 | const currentUser = JSON.parse(localStorage.getItem('currentUser')) |
| 149 | 155 | ||
| 150 | - // 检查是否需要认证 | 156 | + // 检查当前路由是否需要认证 |
| 151 | - if (authRequiredRoutes.some(route => to.path.startsWith(route))) { | 157 | + const needAuth = authRequiredRoutes.some((route) => { |
| 152 | - if (!currentUser) { | 158 | + // 如果是正则匹配模式 |
| 153 | - // 未登录时重定向到登录页面 | 159 | + if (route.regex) { |
| 154 | - next({ path: '/login', query: { redirect: to.fullPath } }) | 160 | + return new RegExp(`^${route.path}$`).test(to.path) |
| 155 | - return | 161 | + } |
| 162 | + // 如果是精确匹配模式 | ||
| 163 | + if (route.exact) { | ||
| 164 | + return to.path === route.path | ||
| 156 | } | 165 | } |
| 166 | + // 默认前缀匹配模式 | ||
| 167 | + // 判断路由路径是否以指定路径开头,用于匹配需要认证的路由及其子路由 | ||
| 168 | + // 例如: /profile/courses 应该匹配 /profile 规则 | ||
| 169 | + return to.path.startsWith(route.path) | ||
| 170 | + }) | ||
| 171 | + | ||
| 172 | + if (needAuth && !currentUser) { | ||
| 173 | + // 未登录时重定向到登录页面 | ||
| 174 | + next({ path: '/login', query: { redirect: to.fullPath } }) | ||
| 175 | + return | ||
| 157 | } | 176 | } |
| 158 | 177 | ||
| 159 | next() | 178 | next() | ... | ... |
-
Please register or login to post a comment