# 登录跳转首页修复说明 ## 🎯 需求 1. 登录成功后自动跳转到首页 2. 访问 `/` 时自动重定向到 `/home` ## 📋 问题分析 ### 原来的问题 **登录流程**: ``` 用户登录 ↓ 调用 handleLogin ↓ 保存 token 和 authorityMenus ↓ 显示"登录成功!" ↓ window.location.reload() ← ❌ 刷新当前页面(/login) ↓ 停留在登录页面 ❌ ``` **问题**: - 登录成功后刷新了登录页面 - 虽然路由守卫会检测到 token 并重定向到首页 - 但是刷新操作会导致页面停留在 `/login` ### 路由守卫逻辑 `src/router/index.js` 中的路由守卫: ```javascript router.beforeEach((to, from, next) => { const token = getToken() if (!token && to.name !== 'login') { // 未登录且访问非登录页 → 跳转到登录页 next({ name: 'login' }) } else if (!token && to.name === 'login') { // 未登录且访问登录页 → 允许访问 next() } else if (token && to.name === 'login') { // 已登录且访问登录页 → 重定向到首页 next({ name: homeName }) // homeName = 'home' } else { // 其他情况 → 允许访问 next() } }) ``` **说明**: - 如果已登录(有 token)且访问登录页,会重定向到首页 - 但是 `window.location.reload()` 会刷新当前页面,不会触发路由跳转 ### 主路由重定向配置 `src/utils/uiTool.js` 中的主路由配置: ```javascript let mainRoute = { path: '/', name: '主视图', redirect: '/home', // ← 访问 / 时重定向到 /home component: Main, children: [] } ``` **说明**: - 访问 `/` 时会自动重定向到 `/home` - 前提是 `/home` 路由存在(从后端权限菜单生成) ## ✅ 解决方案 ### 修改登录成功后的跳转逻辑 **修改文件**:`src/views/login/login.vue` **修改前**: ```javascript async handleSubmit({ userName, password }) { try { let userFrom = { name: userName, password: password } await this.handleLogin({ userFrom, Main, ParentView, Page404 }) this.$Message.success('登录成功!') window.location.reload() // ❌ 刷新当前页面(/login) } catch (error) { // 错误处理 } } ``` **修改后**: ```javascript async handleSubmit({ userName, password }) { try { let userFrom = { name: userName, password: password } await this.handleLogin({ userFrom, Main, ParentView, Page404 }) this.$Message.success('登录成功!') // ✅ 跳转到首页(使用 location.href 触发完整页面加载) setTimeout(() => { window.location.href = window.location.origin + window.location.pathname + '#/' }, 500) } catch (error) { // 错误处理 } } ``` **改进点**: - ✅ 使用 `window.location.href` 跳转到 `#/` - ✅ 触发完整的页面加载 - ✅ 路由会重定向到 `/home` - ✅ 延迟 500ms 确保提示信息显示 ## 📊 新的登录流程 ### 完整流程 ``` 用户输入用户名密码 ↓ 点击登录 ↓ 调用 handleLogin action ↓ 调用登录接口 ↓ 保存 token 到 localStorage ↓ 保存用户信息到 Vuex ↓ 调用 setAuthorityMenus ├─ 尝试获取权限菜单 ├─ 如果失败,使用默认菜单 └─ 保存到 localStorage.authorityMenus ↓ 显示"登录成功!"提示 ↓ 延迟 500ms ↓ 跳转到 #/ (window.location.href) ↓ 触发完整页面加载 ↓ 框架初始化 ↓ 从 localStorage 读取 authorityMenus ↓ 生成路由(包括首页) ↓ 访问 / 路由 ↓ 重定向到 /home ✅ ↓ 显示首页 ✅ ``` ### 路由重定向流程 ``` 访问 #/ ↓ 匹配主路由 { path: '/', redirect: '/home' } ↓ 重定向到 /home ↓ 匹配首页路由 { path: '/home', component: HomePage } ↓ 显示首页组件 ✅ ``` ### 已登录用户访问登录页 ``` 已登录用户访问 #/login ↓ 路由守卫检测到 token ↓ 检测到访问登录页 ↓ 重定向到首页 next({ name: 'home' }) ↓ 显示首页 ✅ ``` ## 🎯 关键点说明 ### 1. 为什么使用 `window.location.href` 而不是 `this.$router.push`? **`this.$router.push({ path: '/' })`**: - 只是客户端路由跳转 - 不会重新加载页面 - 不会重新初始化框架 - 不会重新从 localStorage 读取 authorityMenus **`window.location.href = '#/'`**: - 触发完整的页面加载 - 重新初始化框架 - 重新从 localStorage 读取 authorityMenus - 重新生成路由 - 确保路由和菜单正确加载 ### 2. 为什么延迟 500ms? ```javascript setTimeout(() => { window.location.href = window.location.origin + window.location.pathname + '#/' }, 500) ``` **原因**: - 让"登录成功!"提示信息有时间显示 - 给用户更好的体验 - 确保 localStorage 写入完成 ### 3. URL 构造说明 ```javascript window.location.origin + window.location.pathname + '#/' ``` **示例**: - `window.location.origin` = `http://localhost:8080` - `window.location.pathname` = `/` 或 `/demo-project/` - 最终 URL = `http://localhost:8080/#/` 或 `http://localhost:8080/demo-project/#/` **为什么这样构造**: - 兼容不同的部署路径 - 确保 hash 路由正确 - 避免硬编码 URL ### 4. 主路由的 redirect 配置 ```javascript let mainRoute = { path: '/', redirect: '/home', component: Main, children: [ { path: '/home', name: 'home', component: HomePage }, // ... 其他路由 ] } ``` **工作原理**: - 访问 `/` 时,自动重定向到 `/home` - `/home` 路由由后端权限菜单生成 - 如果后端没有返回首页配置,会使用默认菜单配置 ## ✅ 验证清单 ### 登录流程验证 - ✅ 访问登录页面 - ✅ 输入用户名密码 - ✅ 点击登录 - ✅ 显示"登录成功!"提示 - ✅ 自动跳转到首页 - ✅ 首页正确显示 - ✅ 菜单正确显示 ### 路由重定向验证 - ✅ 登录后访问 `#/` 自动重定向到 `#/home` - ✅ 已登录状态访问 `#/login` 自动重定向到 `#/home` - ✅ 未登录状态访问 `#/home` 自动重定向到 `#/login` ### 刷新页面验证 - ✅ 登录后刷新页面,停留在当前页面 - ✅ 菜单和路由保持正确 - ✅ 用户信息保持正确 ## 🔧 相关配置 ### 路由守卫配置 **文件**:`src/router/index.js` ```javascript export const setupRouterGuards = (router, ViewUI, homeName = 'home') => { router.beforeEach((to, from, next) => { const token = getToken() ViewUI.LoadingBar.start() if (!token && to.name !== 'login') { // 未登录 → 跳转到登录页 next({ name: 'login' }) } else if (!token && to.name === 'login') { // 未登录访问登录页 → 允许 next() } else if (token && to.name === 'login') { // 已登录访问登录页 → 重定向到首页 next({ name: homeName }) } else { // 其他情况 → 允许 next() } }) router.afterEach(to => { ViewUI.LoadingBar.finish() window.scrollTo(0, 0) }) return router } ``` ### 主路由配置 **文件**:`src/utils/uiTool.js` ```javascript static getRoutes(Main, ParentView, Page404) { let mainRoute = { path: '/', name: '主视图', redirect: '/home', component: Main, meta: { title: '首页', notCache: true }, children: [] } // 从 localStorage 读取权限菜单 if (localStorage.authorityMenus && localStorage.authorityMenus !== 'undefined') { let authorityMenus = JSON.parse(localStorage.authorityMenus) || [] if (authorityMenus && authorityMenus.length > 0) { let menus = uiTool.transformTree(authorityMenus) let curRoutes = uiTool.menuToRoute(menus, ParentView, Page404) // 使用后端返回的路由(包括首页) mainRoute.children = curRoutes } } return mainRoute } ``` ## 💡 最佳实践 ### 1. 登录后的跳转 **推荐**: ```javascript // 使用 location.href 触发完整页面加载 window.location.href = window.location.origin + window.location.pathname + '#/' ``` **不推荐**: ```javascript // 只刷新当前页面,不跳转 window.location.reload() // 客户端路由跳转,不重新加载 this.$router.push({ path: '/' }) ``` ### 2. 路由守卫 **推荐**: - 在路由守卫中统一处理登录状态检查 - 已登录访问登录页时自动重定向到首页 - 未登录访问受保护页面时自动重定向到登录页 ### 3. 主路由配置 **推荐**: - 设置 `redirect: '/home'` 确保访问 `/` 时重定向到首页 - 从后端权限菜单生成路由 - 提供默认菜单配置作为降级方案 ## 📝 总结 ### 修改内容 - ✅ 修改了登录成功后的跳转逻辑 - ✅ 使用 `window.location.href` 跳转到首页 - ✅ 触发完整页面加载 - ✅ 确保路由和菜单正确初始化 ### 效果 - ✅ 登录成功后自动跳转到首页 - ✅ 访问 `/` 自动重定向到 `/home` - ✅ 已登录访问登录页自动重定向到首页 - ✅ 用户体验更流畅 --- **登录跳转首页功能已完成!** 🎉 现在登录成功后会自动跳转到首页,访问 `/` 也会正确重定向到 `/home`。