一、什么是动态路由?为什么需要它?
1.1 举个栗子 🌰
假设你正在开发一个企业管理系统:
• 管理员可以访问:员工管理、财务统计等页面
• 普通员工只能访问:个人考勤、任务列表
这时候就需要根据用户的身份动态决定他能看到哪些页面——这就是动态路由的核心作用!
1.2 技术大白话
• 前端动态路由:用户登录后,前端根据权限动态加载不同的页面菜单
• 后端动态路由:后端根据用户角色控制接口访问权限
二、手把手搭建环境
2.1 准备工具
工具 | 下载地址 | 作用说明 |
---|---|---|
Node.js (v16+) | nodejs.org | 运行前端Vue项目 |
Java JDK 11 | Oracle JDK | 运行Spring Boot后端 |
VS Code | code.visualstudio.com | 代码编辑器 |
2.2 创建项目
# 前端:创建Vue3项目
npm create vue@latest dynamic-router-demo
# 后端:使用Spring Initializr生成项目
# 勾选:Spring Web, Spring Security, Spring Data JPA, MySQL Driver
三、前端实现(Vue3)
3.1 基础路由配置
// src/router/index.js
import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({
history: createWebHistory(),
routes: [
{ path: '/', redirect: '/login' },
{ path: '/login', component: () => import('@/views/Login.vue') },
// 其他公共路由...
]
})
3.2 动态加载路由(小白友好版)
<!-- src/views/Login.vue -->
<script setup>
import { ref } from 'vue'
import { useRouter } from 'vue-router'
import axios from 'axios'
const router = useRouter()
const username = ref('')
const password = ref('')
// ✅ 点击登录按钮触发
const handleLogin = async () => {
// 1. 发送登录请求
const res = await axios.post('http://localhost:8080/api/login', {
username: username.value,
password: password.value
})
// 2. 获取用户权限(假设返回admin或user)
const userRole = res.data.role
// 3. 根据角色加载不同路由
const routesConfig = {
admin: [
{ path: '/admin', component: 'AdminDashboard.vue' },
{ path: '/user-manage', component: 'UserManage.vue' }
],
user: [
{ path: '/dashboard', component: 'UserDashboard.vue' }
]
}
// 4. 动态添加路由
routesConfig[userRole].forEach(route => {
router.addRoute({
path: route.path,
component: () => import(`@/views/${route.component}`)
})
})
// 5. 跳转到首页
router.push('/dashboard')
}
</script>
四、后端实现(Spring Boot)
4.1 数据库准备
-- 创建用户表
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) UNIQUE,
password VARCHAR(100),
role VARCHAR(20) DEFAULT 'user'
);
-- 插入测试数据
INSERT INTO users (username, password, role)
VALUES ('admin', '123456', 'admin'),
('user1', '123456', 'user');
4.2 用户登录接口
// LoginController.java
@RestController
@RequestMapping("/api")
public class LoginController {
@Autowired
private UserRepository userRepository;
@PostMapping("/login")
public ResponseEntity<?> login(@RequestBody User loginUser) {
// 1. 查询用户是否存在
User user = userRepository.findByUsername(loginUser.getUsername());
// 2. 简单密码验证(实际项目要加密!)
if(user != null && user.getPassword().equals(loginUser.getPassword())) {
return ResponseEntity.ok().body(Map.of(
"role", user.getRole()
));
}
return ResponseEntity.status(401).body("登录失败");
}
}
4.3 权限控制配置
// SecurityConfig.java
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeHttpRequests()
.requestMatchers("/api/login").permitAll() // 登录接口放行
.anyRequest().authenticated() // 其他接口需要认证
.and()
.httpBasic(); // 简单认证(实际项目建议用JWT)
return http.build();
}
}
五、全流程测试
5.1 测试步骤
- 启动Spring Boot后端:
mvn spring-boot:run
- 启动Vue前端:
npm run dev
- 访问
http://localhost:5173/login
- 测试账号:
• 管理员:admin/123456 → 能看到管理菜单
• 普通用户:user1/123456 → 只能看到基础页面
5.2 常见问题排查
现象 | 可能原因 | 解决办法 |
---|---|---|
页面空白 | 路由路径错误 | 检查router.addRoute 的path配置 |
接口返回401 | 未携带认证信息 | 检查登录是否成功并保存token |
动态路由加载失败 | 组件路径拼写错误 | 确认component 路径与实际文件匹配 |
六、下一步学习建议
-
提升安全性
• 学习使用bcrypt
加密密码
• 用JWT替代简单认证 -
扩展功能
• 添加路由菜单的动态渲染
• 实现按钮级权限控制 -
推荐资源
• Vue3官方教程
• Spring Boot入门指南
动手实践是学习的最佳途径! 遇到问题欢迎在评论区留言,我们一起讨论解决~ 🚀