elegant-router 详细介绍
elegant-router 是一个为 Vue 3 设计的优雅、类型安全的路由库,它让 Vue Router 的使用更加现代化和类型安全。
1. 是什么?
1.1 核心定位
// 传统 Vue Router
const routes = [
{ path: '/user', component: User }
] // ❌ 没有类型安全
// 使用 elegant-router
const routes = elegantRouter({
user: route('/user', () => import('./User.vue'))
}) // ✅ 完全类型安全
2. 核心特性
2.1 类型安全的路由
import { elegantRouter, route } from 'elegant-router'
// 定义路由
export const routes = elegantRouter({
// 基础路由
home: route('/', () => import('@/views/Home.vue')),
// 带参数的路由
user: route('/user/:id', () => import('@/views/User.vue'), {
props: true // 自动传递参数
}),
// 嵌套路由
dashboard: route('/dashboard', () => import('@/views/Dashboard.vue'), {
children: {
overview: route('overview', () => import('@/views/Dashboard/Overview.vue')),
settings: route('settings', () => import('@/views/Dashboard/Settings.vue'))
}
})
})
// 使用时的类型安全
const router = useRouter()
// ✅ 自动补全路由名
router.push({ name: 'user', params: { id: 1 } })
// ❌ 类型错误:缺少 params
router.push({ name: 'user' })
// ❌ 类型错误:不存在的路由
router.push({ name: 'not-exist' })
2.2 自动生成路由类型
// elegant-router 自动生成的路由类型
type AppRoutes = {
home: { path: '/'; params?: never; query?: any }
user: { path: '/user/:id'; params: { id: string }; query?: any }
dashboard: {
path: '/dashboard';
params?: never;
query?: any;
children: {
overview: { path: 'overview'; params?: never; query?: any }
settings: { path: 'settings'; params?: never; query?: any }
}
}
}
// 使用时获得完整的类型提示
const { name, params, query } = routeTo('user', { id: '123' })
// name: 'user'
// params: { id: string }
3. 基本使用
3.1 安装和配置
# 安装
npm install elegant-router
# 或
yarn add elegant-router
// router/index.ts
import { createRouter, createWebHistory } from 'vue-router'
import { elegantRouter, route, setupElegantRouter } from 'elegant-router'
import type { App } from 'vue'
// 1. 定义路由
export const routes = elegantRouter({
// 首页
home: route('/', () => import('@/views/Home.vue')),
// 关于页
about: route('/about', () => import('@/views/About.vue')),
// 用户相关
user: {
// 用户列表
list: route('/users', () => import('@/views/user/List.vue')),
// 用户详情
detail: route('/users/:id', () => import('@/views/user/Detail.vue'), {
props: true
}),
// 用户编辑
edit: route('/users/:id/edit', () => import('@/views/user/Edit.vue'))
},
// 管理后台
admin: route('/admin', () => import('@/views/Admin.vue'), {
meta: { requiresAuth: true, role: 'admin' },
children: {
dashboard: route('', () => import('@/views/admin/Dashboard.vue')),
users: route('users', () => import('@/views/admin/Users.vue'))
}
}),
// 404 页面
notFound: route('/:pathMatch(.*)*', () => import('@/views/404.vue'))
})
// 2. 创建 Vue Router
export const router = createRouter({
history: createWebHistory(),
routes: routes.flat // 转换为 Vue Router 格式
})
// 3. 安装插件
export function setupRouter(app: App) {
app.use(router)
setupElegantRouter(router, routes)
return router
}
3.2 在 main.ts 中使用
// main.ts
import { createApp } from 'vue'
import { setupRouter } from './router'
import App from './App.vue'
async function bootstrap() {
const app = createApp(App)
// 安装路由
await setupRouter(app)
app.mount('#app')
}
bootstrap()
4. 路由跳转
4.1 类型安全的导航
<template>
<div>
<!-- 1. 编程式导航 -->
<button @click="goToUser">用户详情</button>
<!-- 2. 路由链接 -->
<router-link :to="routeTo('user.detail', { id: '123' })">
用户123
</router-link>
</div>
</template>
<script setup lang="ts">
import { useRouter, useRoute } from 'vue-router'
import { routeTo, useRouteParams } from 'elegant-router'
const router = useRouter()
const route = useRoute()
// ✅ 类型安全的跳转
const goToUser = () => {
// 方法1: 使用 routeTo 辅助函数
router.push(routeTo('user.detail', { id: '123' }))
// 方法2: 直接使用 router.push
router.push({
name: 'user.detail',
params: { id: '123' }
})
// ❌ 类型错误:缺少必要参数
// router.push({ name: 'user.detail' })
// ❌ 类型错误:参数类型不匹配
// router.push({ name: 'user.detail', params: { id: 123 } })
}
// 获取路由参数(类型安全)
const params = useRouteParams('user.detail')
// params 类型为 { id: string }
console.log(params.id) // 自动提示 id 属性
</script>
4.2 查询参数和哈希
// 带查询参数的路由
router.push(
routeTo('user.list', null, {
page: 1,
size: 20,
search: 'keyword'
})
)
// 带哈希的路由
router.push(
routeTo('about', null, null, '#section-2')
)
// 完整参数
const to = routeTo(
'user.detail', // 路由名
{ id: '123' }, // 路径参数
{ tab: 'info' }, // 查询参数
'#profile' // 哈希
)
5. 高级功能
5.1 路由守卫
// router/guards.ts
import type { RouteLocationNormalized } from 'vue-router'
import { useAuthStore } from '@/stores/auth'
// 类型安全的守卫
export function authGuard(
to: RouteLocationNormalized,
from: RouteLocationNormalized
) {
const authStore = useAuthStore()
// 检查是否需要认证
if (to.meta.requiresAuth && !authStore.isAuthenticated) {
// 重定向到登录页
return routeTo('login', null, {
redirect: to.fullPath
})
}
// 检查角色权限
if (to.meta.role && !authStore.hasRole(to.meta.role)) {
return routeTo('forbidden')
}
}
5.2 动态路由
// 动态添加路由
import { addRoute } from 'elegant-router'
// 基于权限动态添加路由
function setupDynamicRoutes(userRole: string) {
if (userRole === 'admin') {
addRoute('admin', {
system: route('system', () => import('@/views/admin/System.vue'), {
meta: { requiresAdmin: true }
})
})
}
}
5.3 路由元信息
export const routes = elegantRouter({
dashboard: route('/dashboard', () => import('@/views/Dashboard.vue'), {
// 路由元信息
meta: {
title: '控制台',
requiresAuth: true,
breadcrumb: ['首页', '控制台'],
icon: 'dashboard',
keepAlive: true,
permissions: ['view_dashboard']
},
// 路由独享的守卫
beforeEnter: (to, from) => {
// 类型安全的守卫
console.log(to.params) // 有完整类型提示
}
})
})
6. 工具函数
6.1 路由辅助工具
import {
routeTo, // 生成路由对象
useRouteParams, // 获取类型安全的参数
useRouteQuery, // 获取类型安全的查询参数
useRouteHash, // 获取哈希
getRouteMeta, // 获取路由元信息
resolveRoute, // 解析路由
generatePath // 生成路径
} from 'elegant-router'
// 在组件中使用
const UserDetail = defineComponent({
setup() {
// 获取参数(类型安全)
const params = useRouteParams('user.detail')
const query = useRouteQuery('user.list')
const hash = useRouteHash()
// 获取元信息
const meta = getRouteMeta('dashboard')
// 生成路径
const path = generatePath('user.detail', { id: '123' })
// 输出: /users/123
return { params, path }
}
})
7. 实际项目结构
7.1 推荐的项目结构
src/
├── router/
│ ├── index.ts # 主路由文件
│ ├── types/ # 路由类型定义
│ │ ├── index.ts
│ │ └── meta.ts # 元信息类型
│ ├── guards/ # 路由守卫
│ │ ├── auth.ts
│ │ └── permission.ts
│ └── modules/ # 路由模块
│ ├── auth.routes.ts
│ ├── user.routes.ts
│ └── admin.routes.ts
├── views/ # 页面组件
│ ├── Home.vue
│ ├── user/
│ │ ├── List.vue
│ │ └── Detail.vue
│ └── admin/
│ ├── Dashboard.vue
│ └── Users.vue
└── App.vue7.2 模块化路由示例
// router/modules/auth.routes.ts
export const authRoutes = {
login: route('/login', () => import('@/views/auth/Login.vue')),
register: route('/register', () => import('@/views/auth/Register.vue')),
forgotPassword: route('/forgot-password', () => import('@/views/auth/ForgotPassword.vue'))
}
// router/modules/user.routes.ts
export const userRoutes = {
profile: route('/profile', () => import('@/views/user/Profile.vue'), {
meta: { requiresAuth: true }
}),
settings: route('/settings', () => import('@/views/user/Settings.vue'), {
meta: { requiresAuth: true }
})
}
// router/index.ts
import { authRoutes, userRoutes } from './modules'
export const routes = elegantRouter({
...authRoutes,
...userRoutes,
// 其他路由...
})
8. 与 Vue Router 对比
| 特性 | Vue Router | elegant-router |
|---|---|---|
| 类型安全 | ❌ 有限 | ✅ 完整 |
| 自动补全 | ❌ 无 | ✅ 完整 |
| 路由定义 | 对象数组 | 类型安全对象 |
| 参数验证 | ❌ 运行时 | ✅ 编译时 |
| 元信息 | 松散类型 | 严格类型 |
| 学习成本 | 低 | 中 |
| 适用场景 | 所有项目 | 中大型 TypeScript 项目 |
9. 总结
elegant-router 的核心价值:
✅ 优点:
- 完整的类型安全 - 编译时检查路由
- 优秀的开发体验 - 自动补全、类型提示
- 更好的代码组织 - 模块化、可维护
- 减少运行时错误 - 提前发现路由问题
⚠️ 注意事项:
- 需要 TypeScript 项目
- 学习成本略高
- 更适合中大型项目
🎯 适用场景:
- 使用 Vue 3 + TypeScript 的项目
- 中大型企业级应用
- 需要严格路由管理的项目
- 团队协作,需要规范路由使用
如果你在开发一个 TypeScript 的 Vue 3 项目,并且对代码质量有要求,elegant-router 是一个很不错的选择.
