视频教程 Vue3 + vite + Ts + pinia + 实战 + 源码_哔哩哔哩_bilibili
全局前置守卫
router.beforeEach
router.beforeEach((to, form, next) => { console.log(to, form); next() })
每个守卫方法接收三个参数:
to: Route, 即将要进入的目标 路由对象; from: Route,当前导航正要离开的路由; next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。 next(false): 中断当前的导航。如果浏览器的 URL 改变了 (可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。 next('/') 或者 next({ path: '/' }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。
案例 权限判断
const whileList = ['/'] router.beforeEach((to, from, next) => { let token = localStorage.getItem('token') //白名单 有值 或者登陆过存储了token信息可以跳转 否则就去登录页面 if (whileList.includes(to.path) || token) { next() } else { next({ path:'/' }) } })
全局后置守卫
使用场景一般可以用来做loadingBar
你也可以注册全局后置钩子,然而和守卫不同的是,这些钩子不会接受 next 函数也不会改变导航本身:
router.afterEach((to,from)=>{ Vnode.component?.exposed?.endLoading() })
loadingBar 组件
<template> <div class="wraps"> <div ref="bar" class="bar"></div> </div> </template> <script setup lang='ts'> import { ref, onMounted } from 'vue' let speed = ref<number>(1) let bar = ref<HTMLElement>() let timer = ref<number>(0) const startLoading = () => { let dom = bar.value as HTMLElement; speed.value = 1 timer.value = window.requestAnimationFrame(function fn() { if (speed.value < 90) { speed.value += 1; dom.style.width = speed.value + '%' timer.value = window.requestAnimationFrame(fn) } else { speed.value = 1; window.cancelAnimationFrame(timer.value) } }) } const endLoading = () => { let dom = bar.value as HTMLElement; setTimeout(() => { window.requestAnimationFrame(() => { speed.value = 100; dom.style.width = speed.value + '%' }) }, 500) } defineExpose({ startLoading, endLoading }) </script> <style scoped lang="less"> .wraps { position: fixed; top: 0; width: 100%; height: 2px; .bar { height: inherit; width: 0; background: blue; } } </style>
mian.ts
import loadingBar from './components/loadingBar.vue' const Vnode = createVNode(loadingBar) render(Vnode, document.body) console.log(Vnode); router.beforeEach((to, from, next) => { Vnode.component?.exposed?.startLoading() }) router.afterEach((to, from) => { Vnode.component?.exposed?.endLoading() })