1. <sup id="1kcns"></sup>

    2. <rt id="1kcns"><legend id="1kcns"></legend></rt>
      国产AV巨作丝袜秘书,国产精品久久香蕉免费播放,国产草草影院ccyycom,涩涩爱狼人亚洲一区在线,日本阿v片在线播放免费,国产精品一区二区三区蜜臀,精品一区二区三区在线观看l,av深夜免费在线观看

      vue-router 導(dǎo)航守衛(wèi)中 next 控制實(shí)現(xiàn)

      2020-5-14    seo達(dá)人

      使用 vue-router 的導(dǎo)航守衛(wèi)鉤子函數(shù),某些鉤子函數(shù)可以讓開發(fā)者根據(jù)業(yè)務(wù)邏輯,控制是否進(jìn)行下一步,或者進(jìn)入到指定的路由。


      例如,后臺(tái)管理頁(yè)面,會(huì)在進(jìn)入路由前,進(jìn)行必要登錄、權(quán)限判斷,來決定去往哪個(gè)路由,以下是偽代碼:


      // 全局導(dǎo)航守衛(wèi)

      router.beforEach((to, from, next) => {

       if('no login'){

         next('/login')

       }else if('admin') {

         next('/admin')

       }else {

         next()

       }

      })


      // 路由配置鉤子函數(shù)

      {

       path: '',

       component: component,

       beforeEnter: (to, from, next) => {

         next()

       }

      }


      // 組件中配置鉤子函數(shù)

      {

       template: '',

       beforeRouteEnter(to, from, next) {

         next()

       }

      }

      調(diào)用 next,意味著繼續(xù)進(jìn)行下面的流程;不調(diào)用,則直接終止,導(dǎo)致路由中設(shè)置的組件無法渲染,會(huì)出現(xiàn)頁(yè)面一片空白的現(xiàn)象。


      鉤子函數(shù)有不同的作用,例如 beforEach,afterEach,beforeEnter,beforeRouteEnter,beforeRouteUpdate,beforeRouteLeave,針對(duì)這些注冊(cè)的鉤子函數(shù),要依次進(jìn)行執(zhí)行,并且在必要環(huán)節(jié)有控制權(quán)決定是否繼續(xù)進(jìn)入到下一個(gè)鉤子函數(shù)中。


      以下分析下源碼中實(shí)現(xiàn)的方式,而源碼中處理的邊界情況比較多,需要抓住核心點(diǎn),去掉冗余代碼,精簡(jiǎn)出便于理解的實(shí)現(xiàn)。


      精簡(jiǎn)源碼核心功能

      總結(jié)下核心點(diǎn):鉤子函數(shù)注冊(cè)的回調(diào)函數(shù),能順序執(zhí)行,同時(shí)會(huì)將控制權(quán)交給開發(fā)者。


      先來一個(gè)能夠注冊(cè)回調(diào)函數(shù)的類:


      class VueRouter {

       constructor(){

         this.beforeHooks = []

         this.beforeEnterHooks = []


         this.afterHooks = []

       }


       beforEach(callback){

         return registerHook(this.beforeHooks, callback)

       }

       beforeEnter(callback){

         return registerHook(this.beforeEnterHooks, callback)

       }

       afterEach(callback){

         return registerHook(this.afterHooks, callback)

       }

      }

      function registerHook (list, fn) {

       list.push(fn)

       return () => {

         const i = list.indexOf(fn)

         if (i > -1) list.splice(i, 1)

       }

      }

      聲明的類,提供了 beforEach 、beforeEnter 和 afterEach 來注冊(cè)必要的回調(diào)函數(shù)。


      抽象出一個(gè) registerHook 公共方法,作用:


      注冊(cè)回調(diào)函數(shù)

      返回的函數(shù),可以取消注冊(cè)的回調(diào)函數(shù)

      使用一下:


      const router = new VueRouter()


      const beforEach = router.beforEach((to, from, next) => {

       console.log('beforEach');

       next()

      })

      // 取消注冊(cè)的函數(shù)

      beforEach()

      以上的回調(diào)函數(shù)會(huì)被取消,意味著不會(huì)執(zhí)行了。



      router.beforEach((to, from, next) => {

       console.log('beforEach');

       next()

      })


      router.beforeEnter((to, from, next) => {

       console.log('beforeEnter');

       next()

      })


      router.afterEach(() => {

       console.log('afterEach');

      })

      以上注冊(cè)的鉤子函數(shù)會(huì)依次執(zhí)行。beforEach 和 beforeEnter 的回調(diào)接收內(nèi)部傳來的參數(shù),同時(shí)通過調(diào)用 next 可繼續(xù)走下面的回調(diào)函數(shù),如果不調(diào)用,則直接被終止了。

      最后一個(gè) afterEach 在上面的回調(diào)函數(shù)都執(zhí)行后,才被執(zhí)行,且不接收任何參數(shù)。


      先來實(shí)現(xiàn)依次執(zhí)行,這是最簡(jiǎn)單的方式,在類中增加 run 方法,手動(dòng)調(diào)用:



      class VueRouter {

       // ... 其他省略,增加 run 函數(shù)


       run(){

         // 把需要依次執(zhí)行的回調(diào)存放在一個(gè)隊(duì)列中

         let queue = [].concat(

           this.beforeHooks,

           this.afterHooks

         )

         

         for(let i = 0; i < queue.length; i++){

           if(queue(i)) {

             queue(i)('to', 'from', () => {})

           }

         }

       }

      }


      // 手動(dòng)調(diào)用


      router.run()

      打印:


      'beforEach'

      'beforeEnter'

      上面把要依次執(zhí)行的回調(diào)函數(shù)聚合在一個(gè)隊(duì)列中執(zhí)行,并傳入必要的參數(shù),但這樣開發(fā)者不能控制是否進(jìn)行下一步,即便不執(zhí)行 next 函數(shù),依然會(huì)依次執(zhí)行完隊(duì)列的函數(shù)。


      改進(jìn)一下:


      class VueRouter {

       // ... 其他省略,增加 run 函數(shù)


       run(){

         // 把需要依次執(zhí)行的回調(diào)存放在一個(gè)隊(duì)列中

         let queue = [].concat(

           this.beforeHooks,

           this.afterHooks

         )

         queue[0]('to', 'from', () => {

           queue[1]('to', 'from', () => {

            console.log('調(diào)用結(jié)束');

           })

         })

       }

      }


      router.beforEach((to, from, next) => {

       console.log('beforEach');

       // next()

      })


      router.beforeEnter((to, from, next) => {

       console.log('beforeEnter');

       next()

      })

      傳入的 next 函數(shù)會(huì)有調(diào)用下一個(gè)回調(diào)函數(shù)的行為,把控制權(quán)交給了開發(fā)者,調(diào)用了 next 函數(shù)會(huì)繼續(xù)執(zhí)行下一個(gè)回調(diào)函數(shù);不調(diào)用 next 函數(shù),則終止了隊(duì)列的執(zhí)行,所以打印結(jié)果是:


      'beforEach'

      上面實(shí)現(xiàn)有個(gè)弊端,代碼不夠靈活,手動(dòng)一個(gè)個(gè)調(diào)用,在真實(shí)場(chǎng)景中無法確定注冊(cè)了多少個(gè)回調(diào)函數(shù),所以需要繼續(xù)抽象成一個(gè)功能更強(qiáng)的方法:


      function runQueue (queue, fn, cb) {

       const step = index => {

         // 隊(duì)列執(zhí)行結(jié)束了

         if (index >= queue.length) {

           cb()

         } else {

           // 隊(duì)列有值

           if (queue[index]) {

             // 傳入隊(duì)列中回調(diào),做一些必要的操作,第二個(gè)參數(shù)是為了進(jìn)行下一個(gè)回調(diào)函數(shù)

             fn(queue[index], () => {

               step(index + 1)

             })

           } else {

             step(index + 1)

           }

         }

       }

       // 初次調(diào)用,從第一個(gè)開始

       step(0)

      }

      runQueue 就是執(zhí)行隊(duì)列的通用方法。


      第一個(gè)參數(shù)為回調(diào)函數(shù)隊(duì)列, 會(huì)依次取出來;

      第二個(gè)參數(shù)是函數(shù),它接受隊(duì)列中的函數(shù),進(jìn)行一些其他處理;并能進(jìn)行下個(gè)回調(diào)函數(shù)的執(zhí)行;

      第三個(gè)參數(shù)是隊(duì)列執(zhí)行結(jié)束后調(diào)用。

      知道了這個(gè)函數(shù)的含義,來使用一下:



      class VueRouter {

       // ... 其他省略,增加 run 函數(shù)


       run(){

         // 把需要依次執(zhí)行的回調(diào)存放在一個(gè)隊(duì)列中

         let queue = [].concat(

           this.beforeHooks,

           this.beforeEnterHooks

         )


         // 接收回到函數(shù),和進(jìn)行下一個(gè)的執(zhí)行函數(shù)

         const iterator = (hook, next) => {

           // 傳給回調(diào)函數(shù)的參數(shù),第三個(gè)參數(shù)是函數(shù),交給開發(fā)者調(diào)用,調(diào)用后進(jìn)行下一個(gè)

           hook('to', 'from', () => {

             console.log('執(zhí)行下一個(gè)回調(diào)時(shí),處理一些相關(guān)信息');

             next()

           })

         }


         runQueue(queue, iterator, () => {


           console.log('執(zhí)行結(jié)束');

           // 執(zhí)行 afterEach 中的回調(diào)函數(shù)

           this.afterHooks.forEach((fn) => {

             fn()

           })

         })

       }

      }

      // 注冊(cè)

      router.beforEach((to, from, next) => {

       console.log('beforEach');

       next()

      })


      router.beforeEnter((to, from, next) => {

       console.log('beforeEnter');

       next()

      })


      router.afterEach(() => {

       console.log('afterEach');

      })


      router.run();

      從上面代碼可以看出來,每次把隊(duì)列 queue 中的回調(diào)函數(shù)傳給 iterator , 用 hook 接收,并調(diào)用。

      傳給 hook 必要的參數(shù),尤其是第三個(gè)參數(shù),開發(fā)者在注冊(cè)的回調(diào)函數(shù)中調(diào)用,來控制進(jìn)行下一步。

      在隊(duì)列執(zhí)行完畢后,依次執(zhí)行 afterHooks 的回調(diào)函數(shù),不傳入任何參數(shù)。


      所以打印結(jié)果為:


      beforEach

      執(zhí)行下一個(gè)回調(diào)時(shí),處理一些相關(guān)信息

      beforeEnter

      執(zhí)行下一個(gè)回調(diào)時(shí),處理一些相關(guān)信息

      執(zhí)行結(jié)束

      afterEach

      以上實(shí)現(xiàn)的非常巧妙,再看 Vue-router 源碼這塊的實(shí)現(xiàn)方式,相信你會(huì)豁然開朗。

      日歷

      鏈接

      個(gè)人資料

      存檔

      主站蜘蛛池模板: 久久综合色之久久综合色| 亚洲国产精品自产在线播放| 2019国产精品青青草原| 在线天堂最新版资源| 国产精品无需播放器在线播放| 欧美成人精品手机在线| 精品精品亚洲高清a毛片| 熟妇自搞| 无码中文av有码中文av| 最新国产AV最新国产在钱| 无码人妻久久一区二区三区蜜桃 | 高清在线一区二区三区视频| 亚洲乱码中文字幕小综合| 亚洲伊人久久精品影院| 97精品久久天干天天天按摩| 亚洲日韩AV无码专区影院| 婷婷伊人綜合中文字幕小说| 亚洲欧美日韩久久精品| 国产精品成人久久电影| 日本久久99成人网站| 四虎永久在线精品免费看| 精品国产杨幂在线观看福利 | 精品偷拍视频在线观看| 涩涩av| 蜜桃亚洲一区二区三区四| 羞羞成人一区| 国产精品爽爽ⅴa在线观看| 色福利网| 日本一极品久久99精品| 免费看久久妇女高潮a| 国产精品嫩草99av在线| 四虎成人精品国产一区a| 永新县| 91干逼视频| 亚洲成人自拍| 国产一区二区三区在线观看免费 | 亚洲 欧美 动漫 少妇 自拍| 国产精品粉嫩嫩在线观看| 51国产| 国产精品偷伦费观看一次| 国内揄拍国内精品对白86|