vue-router 高阶——导航守卫

老规矩,先来解读下官方文档:

vue-router提供的导航守卫主要用来通过跳转或取消的方式来守卫导航。( 简单说,导航守卫就是在路由跳转的时候的一些钩子函数,当从一个页面跳转到另一个页面时,可以在跳转前、中、后做一些事情,我们可以控制路由的跳转 )。

 

导航守卫可分为 三大类:( 全局守卫、路由专享守卫、组件守卫)

一、全局守卫又可分为三个:

(1)全局前置守卫:(项目必用!!!)

router.beforeEach( to,from,next ) =>{ }

(2)全局解析守卫:

router.beforeResolve( to,from,next ) =>{ }

(3)全局后置守卫:

router.afterEach( to,from )=>{ }

二、路由专享守卫:

const router = new VueRouter({
  routes: [
    {
      path: '/play',
      component: Play,
      beforeEnter: (to, from, next) => {}
    }
  ]
})

三、组件中的守卫:

(1)beforeRouteEnter

(2)beforeRouteUpdate

(3)beforeRouteLeave

export default {
    name:'play',
    beforeRouteEnter(to,from,next){

    },
    beforeRouteUpdate(to,from,next){

    },
    beforeRouteLeave(to,from,next){

    }
}

****************** 详解 ***********************************

全局前置守卫 router.beforeEach( ( to,from,next)=>{ } ):

1、常用于登录验证;

2、使用 router.beforeEach 可注册一个全局前置守卫;

3、每当一个导航被触发时,首先被调用的总是全局前置守卫 ;

4、该守卫接受三个参数:to、from、next,三个参数意思分别是:

   to —— 即将要进入的目标路由对象(路由对象);

   from —— 当前导航正要离开的路由(路由对象);

   next —— 此方法,必须调用,如果想跳转的话,否则路由将不会跳转(function)。

router.beforeEach((to,from,next)=>{
    console.log(to)
    console.log(from)
    console.log(next)
    next()
})

上边代码,我们分别打印下这三个参数看下:

从首页(根路径)路由名字为first的页面 跳转到 路由名字 为play页面;

to :正是跳转后的目标路有对象play;

 

to.path 和to.fullPath的区别:

to.path - 当前的路径,始终解析为绝对路径;to.fullPath - 完整的解析URL包含查询参数和哈希。

 

from:是之前的路由对象 first。

 

next:则是一个函数,next函数决定路由是否跳转;

 

 

next( ) 参数问题:

next( false) 可传false,当用户点击浏览器后退按钮时,url地址会重置到from路由对象的地址(通俗说,就是路由不会跳转了!!!)

next( "/")或者 next({path:"/"})可以传路径,它会跳转到不同地址。例如:下边当用户访问路由名为play对应的页面时候,它会被终止,直接会被重定向到路径为 “ /news ” 的页面。

router.beforeEach((to,from,next)=>{
    if(to.name == "play"){
        next({path:"/news"})
    }
    next()
})

全局解析守卫 router.beforeResolve( ( to,from,next)=>{ } )

官方文档:2.5.0新增的一个守卫,在导航被确认之前同时在所有组件守卫和异步路由被解析之后(加载完之后),解析守卫会被调用。。。

 

全局后置钩子router.afterEach( ( to,from)=>{ } )

与守卫不同的是,此钩子函数不会接受next函数,也不会改变导航本身。。。是在全局解析守卫之后被调用。。。

 

路由独享守卫beforeEnter : ( to,from,next)=>{ } 

const router = new VueRouter({
  routes: [
    {
      path: '/play',
      component: Play,
      beforeEnter: (to, from, next) => {}
    }
  ]
})

 

组件内守卫beforeRouterEnter : ( to,from,next)=>{ }

export default {
    name:'play',
    beforeRouteEnter(to,from,next){
      // 在渲染组件前调用,不能获取this,组件实例还未被挂载
        next()
    },
    beforeRouteUpdate(to,from,next){
      // 在当前路由改变,但当前组件被复用时调用, 
      // 比如:带有动态参数的路径,/foo/1  跳转  /foo/2 时,
      // 该钩子函数被调用。(可访问组件实例this) 
        next()
    },
    beforeRouteLeave(to,from,next){
     // 离开该组件对应的路由时,该钩子函数会被调用
        next()
    }
}  

beforeRouterEnter  守卫不能够访问this,因为守卫在导航确认前被掉用,即将登场的新组件还未被创建。。。

当然如果你非要在此守卫中用到this,官方也给出了一个方法,你可以在next函数中传一个回调函数,并把实例作为参数传到回调函数中去,这样您就可以使用this了!!!!(补充下:next中的回调在组件加载完之后执行,最后我整理了一张完整的执行顺序图)

export default {
    name:'play',
    beforeRouteEnter(to,from,next){
        next((_this)=>{
            // 通过 _this来访问实例
        })
    }
}

《《《官方提醒》》》

beforeRouterEnter是支持给next函数传递回调的唯一守卫;

对于beforeRouterUpdate守卫 和 beforeRouterLeave守卫来说,this已经可以用了,所以不支持传递回调,也没意义!!!

 

组件内守卫beforeRouterUpdate : ( to,from,next)=>{ } 

下边例子中,路由页 "/news/:xxx" 会被复用,beforeRouterUpdate 守卫会被触发!!!

<template>
  <div>
    <div v-for="item in my_data" :key="item.id">
      <router-link :to="'/news/' +item.id">{{item.name}}</router-link>
    </div>
    <h1>{{this.$route.params.id}}</h1>
  </div>
  
</template>

<script>
export default {
    name: "news",
    data() {
        return {
            my_data: [
                { name: "java", id: "1" },
                { name: "python", id: "2" },
                { name: "javascript", id: "3" }
            ]
        };
    },
    beforeRoutEnter(to,from,next){
        console.log('news中组件内部钩子函数——beforeRouteUpdate')
        next()
    },
    beforeRouteUpdate(to,from,next){
        console.log('news中组件内部钩子函数——beforeRouteUpdate')
        next()
    },
    beforeRouteLeave(to,from,next){
        console.log('组件内部钩子函数——beforeRouteLeave)
        next()
    },
};
</script>
const router = new VueRouter({
  routes:[
    {
       path:'/news/:id',
       component:News,
       beforeEnter:(to,from,next)=>{
         console.log('news路由中的 路由独享钩子函数——beforeEnter')
         next()
       }
    }
  ]
})
router.beforeEach((to,from,next)=>{
    console.log('全局守卫——beforeEach')
    next()
})
router.beforeResolve((to,from,next)=>{
    console.log('全局守卫——beforeResolve')
    next()
})
router.afterEach((to,from)=>{
    console.log('全局守卫——afterEach')
})

上边代码有几个注意点:

1、从一个普通组件,切换到一个可复用的组件,先来看下执行顺序:

2、当切换可复用的页面时,也就是从 "/news/:1"  ——> "/news/:2"  ——> "/news/:3"  时,执行顺序:(路由独享守卫和组件内钩子beforeRouteEnter 不再执行!)

 

组件内守卫  beforeRouterLeave: ( to,from,next)=>{ } 

此守卫是在从一个导航切换到另一个导航之后,才执行的。。。通常在此守卫可以做一些禁止用户离开的操作,比如:还未保存的草稿;或者在用户离开此导航时清除setInterval计时器,防止离开之后,计时器还在被调用等等。

router.beforeEach((to,from,next)=>{
    if("用户草稿保存了"){
        next() //允许跳转
    }else{
        next(false) //否则禁止跳转
    }
})

总结:

7个守卫以及生命周期函数执行顺序:

 

 

 

  • 4
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面我来为您介绍一下如何使用vue-router实现用户登录注册功能。 首先,我们需要安装vue-router,可以通过以下命令进行安装: ``` npm install vue-router --save ``` 然后,在main.js中引入并使用vue-router: ``` import VueRouter from 'vue-router' Vue.use(VueRouter) ``` 接下来,我们新建一个router.js文件,用于配置路由。在该文件中,我们需要定义路由路径和路由组件: ``` import Vue from 'vue' import VueRouter from 'vue-router' import Login from './components/Login.vue' import Register from './components/Register.vue' Vue.use(VueRouter) const routes = [ { path: '/login', component: Login }, { path: '/register', component: Register } ] const router = new VueRouter({ routes }) export default router ``` 在上面的代码中,我们定义了两个路由路径:/login和/register,并分别对应了Login和Register两个组件。 接下来,在App.vue中,我们需要使用<router-view>标签来显示路由组件: ``` <template> <div id="app"> <router-view></router-view> </div> </template> ``` 最后,在main.js中引入router.js,并将其挂载到Vue实例中: ``` import Vue from 'vue' import App from './App.vue' import router from './router' Vue.config.productionTip = false new Vue({ router, render: h => h(App), }).$mount('#app') ``` 至此,我们已经完成了基本的路由配置。接下来,我们可以在Login和Register组件中实现具体的登录和注册功能。 在Login组件中,我们可以使用Vue.js提供的v-model指令来绑定表单输入的数据,并在点击登录按钮时向服务器发送请求验证用户名和密码: ``` <template> <div class="login"> <h1>登录</h1> <form> <label>用户名:</label> <input type="text" v-model="username"> <br> <label>密码:</label> <input type="password" v-model="password"> <br> <button @click.prevent="login">登录</button> </form> </div> </template> <script> export default { data() { return { username: '', password: '' } }, methods: { login() { // 向服务器发送请求验证用户名和密码 } } } </script> ``` 而在Register组件中,我们可以使用v-model指令来绑定表单输入的数据,并在点击注册按钮时向服务器发送请求创建新用户: ``` <template> <div class="register"> <h1>注册</h1> <form> <label>用户名:</label> <input type="text" v-model="username"> <br> <label>密码:</label> <input type="password" v-model="password"> <br> <label>确认密码:</label> <input type="password" v-model="confirmPassword"> <br> <button @click.prevent="register">注册</button> </form> </div> </template> <script> export default { data() { return { username: '', password: '', confirmPassword: '' } }, methods: { register() { // 向服务器发送请求创建新用户 } } } </script> ``` 到这里,我们已经完成了一个简单的用户登录注册功能,并使用vue-router实现了路由跳转。当用户访问/login时,会显示Login组件;当用户访问/register时,会显示Register组件。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值