Vite+Vue3+TS(4)整合路由组件Vue-Router之导航守卫

导航的过程为了保持良好的可扩展性,设计了守卫及钩子,守卫可以重定向路由,而钩子则不能修改导航本身。守卫跟钩子有全局定义的,也有路由私有的,全局定义的每次导航都会被调用,而路由私有的则只会导航到相应路由时才会被调用。

全局守卫

全局前置守卫

通过 router.beforeEach 注册一个全局前置守卫

router.beforeEach((to, from) => {
    // 返回 false 以取消导航
    return false
})

可以注册多个全局前置守卫,当导航触发时,全局前置守卫按创建顺序依次调用。

每个守卫方法接收两个参数:

  • to:目标路由
  • from:来源路由

可以返回的值:

  • false:取消当前导航。如果是页内导航,则导航被阻止,页面不会发生跳转,url 也不会发生变更。如果 url 发生变化(比如通过手动修改或者浏览器后退按钮),则会显示空页面。
  • 无返回:继续当前导航。
  • 返回一个路由地址:执行路由跳转,相当于调用一次 router.push(),当前导航被中断,进行一个新的导航。
router.beforeEach(async (to, from) => {
    if (
        // 检查用户是否已登录
        !isAuthenticated &&
        // 避免无限重定向
        to.name !== 'Login'
    ) {
        // 将用户重定向到登录页面
        return { name: 'Login' }
    }
})

可选的第三个参数 next

这个参数在 4.X 版本已经不推荐使用,但是依然支持,如果在入参中添加了该参数,则必须使用该方法进行导航,所以,不要让该参数出现在参数列表中。

全局解析守卫

通过 router.beforeResolve 注册一个全局解析守卫,该守卫与 router.beforeEach 类似,每次导航都会触发,是获取数据或执行任何其他操作(如果用户无法进入页面时你希望避免执行的操作)的理想位置。

router.beforeResolve((to, from) => {
    // 返回 false 以取消导航
    return false
})

全局钩子

全局后置钩子

通过 router.afterEach 注册一个全局后置钩子,钩子不能修改导航本身,但对于分析、更改页面标题、声明页面等辅助功能以及许多其他事情都很有用。

router.afterEach((to, from) => {
    // 发送一个统计信息
    sendToAnalytics(to.fullPath)
})

路由守卫

通过路由配置定义 beforeEnter 守卫,只有在进入路由时才会触发,不会在 paramsqueryhash 改变时触发。例如,从 /users/2 进入到 /users/3 或者从 /users/2#info 进入到 /users/2#projects

const routes = [{
    path: '/users/:id',
    component: () => import('@/views/UserCenter.vue'),
    beforeEnter: (to, from) => {
        // reject the navigation
        return false
    },
}]

beforeEnter 可以定义为一个函数,也可以是一个函数数组。

function removeQueryParams(to) {
    if (Object.keys(to.query).length) {
        return { path: to.path, query: {}, hash: to.hash }
    }
}

function removeHash(to) {
    if (to.hash) return { path: to.path, query: to.query, hash: '' }
}

const routes = [{
    path: '/users/:id',
    component: () => import('@/views/UserCenter.vue'),
    beforeEnter: [removeQueryParams, removeHash],
}, {
    path: '/about',
    component: () => import('@/views/About.vue'),
    beforeEnter: [removeQueryParams],
}]

组件守卫

VUE 的页面是基于组件构建的,在组件内也可以定义路由导航守卫

  • beforeRouteEnter
  • beforeRouteUpdate
  • beforeRouteLeave
const UserDetails = {
    template: `...`,
    beforeRouteEnter(to, from, next) {
        // 在渲染该组件的对应路由被验证前调用
        // 不能获取组件实例 `this`!
        // 因为当守卫执行时,组件实例还没被创建!
    },
    beforeRouteUpdate(to, from) {
        // 在当前路由改变,但是该组件被复用时调用
        // 举例来说,对于一个带有动态参数的路径 `/users/:id`,在 `/users/1` 和 `/users/2` 之间跳转的时候,
        // 由于会渲染同样的 `UserDetails` 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
        // 因为在这种情况发生的时候,组件已经挂载好了,导航守卫可以访问组件实例 `this`
    },
    beforeRouteLeave(to, from) {
        // 在导航离开渲染该组件的对应路由时调用
        // 与 `beforeRouteUpdate` 一样,它可以访问组件实例 `this`
    }
}

beforeRouteEnter 不能访问组件本身,因为该守卫是在组件创建前被调用,所以 beforeRouteEnter 提供了第三个参数 next,在组件创建后执行回调,组件实例作为回调方法的入参。

beforeRouteEnter (to, from, next) {
    next(vm => {
        // 通过 `vm` 访问组件实例
    })
}

beforeRouteUpdate 或者 beforeRouteLeave 则不需要 next 参数,因为这两个守卫被执行时,组件实例都是已经存在的情况。

beforeRouteLeave 通常用来预防用户在还未保存修改前突然离开,通过返回 false 来取消。

beforeRouteLeave (to, from) {
    const answer = window.confirm('页面数据尚未保存,确定要关闭吗!')
    if (!answer) {
        return false
    }
}

如果使用组合 API 和 setup 函数来编写组件,通过 onBeforeRouteUpdateonBeforeRouteLeave 来添加守卫。

完整的导航解析流程

  1. 导航被触发。
  2. 在失活的组件里调用 beforeRouteLeave 守卫。
  3. 调用全局的 beforeEach 守卫。
  4. 在重用的组件里调用 beforeRouteUpdate 守卫(2.2+)。
  5. 在路由配置里调用 beforeEnter。
  6. 解析异步路由组件。
  7. 在被激活的组件里调用 beforeRouteEnter。
  8. 调用全局的 beforeResolve 守卫(2.5+)。
  9. 导航被确认。
  10. 调用全局的 afterEach 钩子。
  11. 触发 DOM 更新。
  12. 调用 beforeRouteEnter 守卫中传给 next 的回调函数,创建好的组件实例会作为回调函数的参数传入。

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vite + Vue 3 + TypeScript 的项目中,你可以使用 Vue Router 来处理路由,并调用接口。 首先,确保你已经安装了 Vue Router 和 axios(或其他用于发送 HTTP 请求的库)。你可以使用以下命令进行安装: ``` npm install vue-router axios ``` 接下来,在你的项目中创建一个 `router` 文件夹,并在其中创建一个 `index.ts` 文件。在该文件中,你可以配置你的路由。以下是一个示例: ```typescript import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'; import Home from '@/views/Home.vue'; import About from '@/views/About.vue'; const routes: Array<RouteRecordRaw> = [ { path: '/', name: 'Home', component: Home, }, { path: '/about', name: 'About', component: About, }, ]; const router = createRouter({ history: createWebHistory(), routes, }); export default router; ``` 在上面的示例中,我们定义了两个路由:`Home` 和 `About`。你可以根据你的需求进行修改和扩展。 然后,在你的入口文件(如 `main.ts`)中,引入并使用你的路由: ```typescript import { createApp } from 'vue'; import App from './App.vue'; import router from './router'; const app = createApp(App); app.use(router); app.mount('#app'); ``` 现在,你可以在你的组件中使用 `vue-router` 进行路由导航和调用接口。例如,在 `Home.vue` 组件中,你可以这样使用: ```vue <template> <div> <h1>Home</h1> <button @click="fetchData">Fetch Data</button> </div> </template> <script> import axios from 'axios'; export default { methods: { fetchData() { axios.get('/api/data').then((response) => { console.log(response.data); }).catch((error) => { console.error(error); }); }, }, }; </script> ``` 在上面的示例中,我们使用了 axios 发送 GET 请求来获取数据。你可以根据你的需求调整和扩展这个例子。 希望这能帮助到你!如果你有任何其他问题,请随时问我。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值