Vue Composition API路由守卫实践指南
Vue Composition API中的路由守卫实践指南
1. 在setup
中使用组件内守卫
在Vue 3的Composition API中,我们可以直接在setup()
函数中使用组件内路由守卫,这为逻辑组织提供了更大的灵活性。
基本用法
import { onBeforeRouteLeave, onBeforeRouteUpdate } from 'vue-router'
export default {
setup() {
// 相当于 beforeRouteLeave
onBeforeRouteLeave((to, from, next) => {
const answer = window.confirm('确定要离开吗?未保存的更改将会丢失')
if (answer) {
next()
} else {
next(false)
}
})
// 相当于 beforeRouteUpdate
onBeforeRouteUpdate((to, from, next) => {
// 对路由变化做出响应...
next()
})
}
}
实践建议
守卫执行顺序:Composition API守卫与Options API守卫可以共存,执行顺序为:
beforeRouteUpdate
(Options API)onBeforeRouteUpdate
(Composition API)beforeRouteLeave
(Options API)onBeforeRouteLeave
(Composition API)
- 异步处理:可以在守卫中直接使用
async/await
处理异步逻辑:
onBeforeRouteLeave(async (to, from, next) => {
const canLeave = await checkUnsavedChanges()
next(canLeave)
})
- 组合式使用:可以将守卫逻辑与其他Composition API功能结合:
import { ref } from 'vue'
import { onBeforeRouteLeave } from 'vue-router'
export default {
setup() {
const hasUnsavedChanges = ref(false)
onBeforeRouteLeave((to, from, next) => {
if (hasUnsavedChanges.value) {
// 显示确认对话框
} else {
next()
}
})
return { hasUnsavedChanges }
}
}
2. 复用守卫逻辑的Composable函数设计
Composition API最大的优势之一是能够将逻辑提取为可复用的Composable函数,路由守卫逻辑也不例外。
基础守卫Composable示例
// useRouteGuard.js
import { onBeforeRouteLeave } from 'vue-router'
export function useUnsavedChangesGuard(hasChanges) {
onBeforeRouteLeave((to, from, next) => {
if (hasChanges.value) {
const answer = window.confirm('您有未保存的更改,确定要离开吗?')
answer ? next() : next(false)
} else {
next()
}
})
}
带参数的进阶Composable
// useAuthGuard.js
import { onBeforeRouteUpdate } from 'vue-router'
export function useAuthGuard(requiredRoles) {
onBeforeRouteUpdate(async (to, from, next) => {
const userRoles = await fetchUserRoles()
const hasPermission = requiredRoles.some(role =>
userRoles.includes(role)
)
hasPermission ? next() : next('/forbidden')
})
}
组合多个守卫
// useCompositeGuards.js
import { useUnsavedChangesGuard } from './useRouteGuard'
import { useAuthGuard } from './useAuthGuard'
export function useCompositeGuards(options) {
if (options.unsavedChanges) {
useUnsavedChangesGuard(options.unsavedChanges)
}
if (options.requiredRoles) {
useAuthGuard(options.requiredRoles)
}
}
实践建议
- 命名约定:Composable函数应以
use
前缀开头,遵循Vue社区约定 - 类型安全:为Composable添加TypeScript类型定义:
// useRouteGuard.ts
import type { Ref } from 'vue'
export function useUnsavedChangesGuard(hasChanges: Ref<boolean>): void {
// 实现...
}
测试策略:由于守卫与路由紧密耦合,建议:
- 使用Jest或Vitest进行单元测试
- 模拟
vue-router
的API - 验证
next()
调用的不同情况
- 性能考虑:避免在Composable中执行重逻辑,必要时使用防抖/节流:
import { debounce } from 'lodash-es'
export function useSearchGuard() {
onBeforeRouteUpdate(debounce((to, from, next) => {
// 处理搜索参数变化
next()
}, 300))
}
总结
Composition API为Vue路由守卫带来了新的可能性:
- 更灵活的代码组织:可以将守卫逻辑与相关功能放在一起
- 更好的复用性:通过Composable函数共享守卫逻辑
- 更强的类型支持:与TypeScript配合更自然
- 更清晰的测试边界:隔离测试守卫逻辑更容易
在实际项目中,建议根据团队习惯选择Options API或Composition API风格的守卫,或者两者结合使用,发挥各自的优势。
评论已关闭