08-导航守卫

Huxzhi大约 2 分钟vue3

一般称为 中间件 ,很重要,

前进后退,设置 权限控制在这里

全局前置守卫

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: '/' }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。

案例 权限判断

完整案例:08.a-全局前置守卫案例-登陆判断路由

const whileList = ['/']
 
router.beforeEach((to, from, next) => {
    let token = localStorage.getItem('token')
    //白名单 有值 或者登陆过存储了token信息可以跳转 否则就去登录页面
    if (whileList.includes(to.path) || token) {
        //另外说一下beforeEach可以定义不止一个,vue会收集你所有定义的路由钩子,所以next的作用不应该是跳转,而是使步骤进行到下一个你定义的钩子
        next()
    } else {
        next({
            path:'/'
        })
    }
})

全局后置守卫

使用场景一般可以用来做 loadingBar 完整案例

你也可以注册全局后置钩子,然而和守卫不同的是,这些钩子不会接受 next 函数也不会改变导航本身:

router.afterEach((to,from)=>{
    Vnode.component?.exposed?.endLoading()
})

loadingBar 组件

    <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()
})

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/qq1195566313/article/details/123699583open in new window