路由守卫

页面结构

<body>
    <div id="app">
        <h1>路由守卫</h1>

        <!-- 路由渲染组件 -->
        <router-view></router-view>

        <br />

        <router-link to="/">跳转首页</router-link>
        <router-link to="/user">跳转会员中心</router-link>
        <router-link to="/product">跳转产品页</router-link>
    </div>
</body>

<script src="./vue.min.js"></script>
<!--要引入路由组件-->
<script src="./vue-router.js"></script>

逻辑结构

const Home = {
    template: `<h1>首页</h1>`
}

const User = {
    template: `<h1>会员中心</h1>`
}

const Product = {
    template: `<h1>产品中心</h1>`
}

const Login = {
    template: `<h1>登录界面</h1>`
}

//创建路由对象
const router = new VueRouter({
    routes: [
        {
            path: '/',
            component: Home,
        },
        {
            path: '/user',
            component: User,
            //给这个路由添加自定义信息
            meta: {
                IsLogin: true
            }
        },
        {
            path: '/product',
            component: Product,
            // 组件内的守卫
            beforeRouteEnter(to, from, next)
            {
                //进入路由前
                // 在渲染该组件的对应路由被 confirm 前调用
                // 不!能!获取组件实例 `this`
                // 因为当守卫执行前,组件实例还没被创建
            },
            beforeRouteUpdate(to, from, next) 
            {
                //更新路由前
                // vue(2.2版本 新增)
                // 在当前路由改变,但是该组件被复用时调用
                // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
                // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
                // 可以访问组件实例 `this`
            },
            beforeRouteLeave(to, from, next)
            {
                //离开路由前
                // 导航离开该组件的对应路由时调用
                // 可以访问组件实例 `this`
            }
        },
        {
            path: '/login',
            component: Login,
        },
    ]
})

//全局前置路由守卫
router.beforeEach((to, from, next) => {
    //to 这个参数代表 去到哪个路由
    //from 这个参数代表 从哪里来
    //next 这个参数代表 是否可以去到下一步
    //我们可以根据to当中是否有meta信息来判断当前的路由是否需要登录
    //这个就是我们常见的判断是否有登录
    var IsLogin = to.meta.IsLogin ? to.meta.IsLogin : false
    //如果IsLogin=true 就说明是需要登录的,否则就不需要登录
    if(IsLogin)
    {
        // 需要登录去到登录界面
        next('/login')
    }else
    {
        //不需要登录直接去到下一步
        next()
    }
})

//全局后置路由守卫
router.afterEach((to, from) => {
    // 你也可以注册全局后置钩子,然而和守卫不同的是,这些钩子不会接受 next 函数也不会改变导航本身
    // console.log('全局后置路由守卫')
})

//在全局中加载路由
var app = new Vue({
    el:'#app',
    router,
})

脚手架中使用方式

const app = createApp(App)
    .use(router)  //挂载路由
    .use(Vant)   //挂载UI组件
    .use(api)  //挂载接口   === install
    .use(VueCookies)
    .mount('#app')


//添加路由守卫做判断是否有无登录
router.beforeEach(async (to, from, next) => {
    if(to.meta.auth)
    {
        //需要登录

        //判断是否有无cookie 
        var LoginUser = app.$cookies.get('LoginUser')

        //没有登录就跳转到登录界面
        if(!LoginUser)
        {
            next('/user/base/login')
            return
        }

        //获取id
        var userid = LoginUser.id ? LoginUser.id : 0;

        //接口请求
        var result = await api.check({userid:userid})

        if(result.code == 0)
        {
            //验证失败
            app.$cookies.remove('LoginUser')

            //跳转了
            next('/user/base/login')
            return
        }else
        {
            //验证成功
            //覆盖cookie
            app.$cookies.set('LoginUser', result.data)

            //让他去到该去的路由
            next()
        }
    }else
    {
        //不需要登录,直接跳转路由
        next()
    }
})
powered by GitbookEdit Time: 2023-04-08 10:28:32