9.0 KiB
9.0 KiB
登录跳转首页修复说明
🎯 需求
- 登录成功后自动跳转到首页
- 访问
/时自动重定向到/home
📋 问题分析
原来的问题
登录流程:
用户登录
↓
调用 handleLogin
↓
保存 token 和 authorityMenus
↓
显示"登录成功!"
↓
window.location.reload() ← ❌ 刷新当前页面(/login)
↓
停留在登录页面 ❌
问题:
- 登录成功后刷新了登录页面
- 虽然路由守卫会检测到 token 并重定向到首页
- 但是刷新操作会导致页面停留在
/login
路由守卫逻辑
src/router/index.js 中的路由守卫:
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 中的主路由配置:
let mainRoute = {
path: '/',
name: '主视图',
redirect: '/home', // ← 访问 / 时重定向到 /home
component: Main,
children: []
}
说明:
- 访问
/时会自动重定向到/home - 前提是
/home路由存在(从后端权限菜单生成)
✅ 解决方案
修改登录成功后的跳转逻辑
修改文件:src/views/login/login.vue
修改前:
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) {
// 错误处理
}
}
修改后:
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?
setTimeout(() => {
window.location.href = window.location.origin + window.location.pathname + '#/'
}, 500)
原因:
- 让"登录成功!"提示信息有时间显示
- 给用户更好的体验
- 确保 localStorage 写入完成
3. URL 构造说明
window.location.origin + window.location.pathname + '#/'
示例:
window.location.origin=http://localhost:8080window.location.pathname=/或/demo-project/- 最终 URL =
http://localhost:8080/#/或http://localhost:8080/demo-project/#/
为什么这样构造:
- 兼容不同的部署路径
- 确保 hash 路由正确
- 避免硬编码 URL
4. 主路由的 redirect 配置
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
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
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. 登录后的跳转
推荐:
// 使用 location.href 触发完整页面加载
window.location.href = window.location.origin + window.location.pathname + '#/'
不推荐:
// 只刷新当前页面,不跳转
window.location.reload()
// 客户端路由跳转,不重新加载
this.$router.push({ path: '/' })
2. 路由守卫
推荐:
- 在路由守卫中统一处理登录状态检查
- 已登录访问登录页时自动重定向到首页
- 未登录访问受保护页面时自动重定向到登录页
3. 主路由配置
推荐:
- 设置
redirect: '/home'确保访问/时重定向到首页 - 从后端权限菜单生成路由
- 提供默认菜单配置作为降级方案
📝 总结
修改内容
- ✅ 修改了登录成功后的跳转逻辑
- ✅ 使用
window.location.href跳转到首页 - ✅ 触发完整页面加载
- ✅ 确保路由和菜单正确初始化
效果
- ✅ 登录成功后自动跳转到首页
- ✅ 访问
/自动重定向到/home - ✅ 已登录访问登录页自动重定向到首页
- ✅ 用户体验更流畅
登录跳转首页功能已完成! 🎉
现在登录成功后会自动跳转到首页,访问 / 也会正确重定向到 /home。