Vue3钩子,路由拦截实现
Vue3 钩子与路由拦截实现
Vue3 中的常用钩子
Vue3 中主要使用组合式 API 的钩子函数,常用的有:
import { onMounted, onUpdated, onUnmounted, ref, reactive } from 'vue'export default {setup() {// 组件挂载后调用onMounted(() => {console.log('组件已挂载')})// 组件更新后调用onUpdated(() => {console.log('组件已更新')})// 组件卸载前调用onUnmounted(() => {console.log('组件即将卸载')})return {// 返回需要在模板中使用的数据和方法}}
}
路由拦截实现(基于 Vue Router 4)
路由拦截主要通过 Vue Router 的导航守卫实现,常用的有全局守卫、路由独享守卫和组件内守卫。
1. 全局路由拦截
在路由实例中配置:
// router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'
import Login from '../views/Login.vue'const routes = [{path: '/',name: 'Home',component: Home,meta: { requiresAuth: true // 需要登录才能访问}},{path: '/login',name: 'Login',component: Login}
]const router = createRouter({history: createWebHistory(),routes
})// 全局前置守卫
router.beforeEach((to, from, next) => {// 检查路由是否需要认证if (to.meta.requiresAuth) {// 检查用户是否已登录(这里假设使用localStorage存储登录状态)const isLoggedIn = localStorage.getItem('token')if (isLoggedIn) {// 已登录,继续导航next()} else {// 未登录,重定向到登录页next('/login')}} else {// 不需要认证,直接导航next()}
})// 全局后置钩子
router.afterEach((to, from) => {// 可以在这里记录页面访问日志等console.log(`导航到 ${to.path}`)
})export default router
2. 路由独享的守卫
在具体路由配置中定义:
const routes = [{path: '/admin',name: 'Admin',component: Admin,meta: { requiresAuth: true, requiresAdmin: true },// 路由独享的守卫beforeEnter: (to, from, next) => {const userRole = localStorage.getItem('role')if (userRole === 'admin') {next()} else {// 没有管理员权限,重定向到首页next('/')}}}
]
3. 组件内的守卫
在组件内部定义:
// 在组件中
export default {// 进入组件前调用beforeRouteEnter(to, from, next) {// 这里不能获取组件实例 `this`// 因为当守卫执行时,组件实例还没被创建next(vm => {// 通过 `vm` 访问组件实例if (vm.checkPermission()) {// 有权限,正常进入} else {// 无权限,处理逻辑}})},// 路由更新时调用(当前路由改变,但组件被复用)beforeRouteUpdate(to, from, next) {// 可以访问组件实例 `this`this.fetchData(to.params.id)next()},// 离开组件时调用beforeRouteLeave(to, from, next) {// 可以访问组件实例 `this`if (this.hasUnsavedChanges) {if (confirm('您有未保存的更改,确定要离开吗?')) {next()} else {next(false) // 取消导航}} else {next()}},methods: {checkPermission() {// 权限检查逻辑return true},fetchData(id) {// 数据获取逻辑}}
}
总结
- Vue3 中使用组合式 API 的钩子函数替代了 Vue2 中的选项式生命周期钩子
- 路由拦截主要通过导航守卫实现,分为全局守卫、路由独享守卫和组件内守卫
- 全局守卫适用于整个应用的路由控制,如登录验证
- 路由独享守卫适用于特定路由的权限控制
- 组件内守卫适用于与组件相关的路由逻辑,如未保存数据的提示
在实际项目中,通常会结合使用这些守卫来实现复杂的路由控制需求。