• <noscript id="ggggg"><dd id="ggggg"></dd></noscript>
    <small id="ggggg"></small> <sup id="ggggg"></sup>
    <noscript id="ggggg"><dd id="ggggg"></dd></noscript>
    <tfoot id="ggggg"></tfoot>
  • <nav id="ggggg"><cite id="ggggg"></cite></nav>
    <nav id="ggggg"></nav>
    成人黃色A片免费看三更小说,精品人妻av区波多野结衣,亚洲第一极品精品无码,欧美综合区自拍亚洲综合,久久99青青精品免费观看,中文字幕在线中字日韩 ,亚洲国产精品18久久久久久,黄色在线免费观看

    vue-router 導航守衛中 next 控制實現

    2020-5-14    seo達人

    使用 vue-router 的導航守衛鉤子函數,某些鉤子函數可以讓開發者根據業務邏輯,控制是否進行下一步,或者進入到指定的路由。


    例如,后臺管理頁面,會在進入路由前,進行必要登錄、權限判斷,來決定去往哪個路由,以下是偽代碼:


    // 全局導航守衛

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

     if('no login'){

       next('/login')

     }else if('admin') {

       next('/admin')

     }else {

       next()

     }

    })


    // 路由配置鉤子函數

    {

     path: '',

     component: component,

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

       next()

     }

    }


    // 組件中配置鉤子函數

    {

     template: '',

     beforeRouteEnter(to, from, next) {

       next()

     }

    }

    調用 next,意味著繼續進行下面的流程;不調用,則直接終止,導致路由中設置的組件無法渲染,會出現頁面一片空白的現象。


    鉤子函數有不同的作用,例如 beforEach,afterEach,beforeEnter,beforeRouteEnter,beforeRouteUpdate,beforeRouteLeave,針對這些注冊的鉤子函數,要依次進行執行,并且在必要環節有控制權決定是否繼續進入到下一個鉤子函數中。


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


    精簡源碼核心功能

    總結下核心點:鉤子函數注冊的回調函數,能順序執行,同時會將控制權交給開發者。


    先來一個能夠注冊回調函數的類:


    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 來注冊必要的回調函數。


    抽象出一個 registerHook 公共方法,作用:


    注冊回調函數

    返回的函數,可以取消注冊的回調函數

    使用一下:


    const router = new VueRouter()


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

     console.log('beforEach');

     next()

    })

    // 取消注冊的函數

    beforEach()

    以上的回調函數會被取消,意味著不會執行了。



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

     console.log('beforEach');

     next()

    })


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

     console.log('beforeEnter');

     next()

    })


    router.afterEach(() => {

     console.log('afterEach');

    })

    以上注冊的鉤子函數會依次執行。beforEach 和 beforeEnter 的回調接收內部傳來的參數,同時通過調用 next 可繼續走下面的回調函數,如果不調用,則直接被終止了。

    最后一個 afterEach 在上面的回調函數都執行后,才被執行,且不接收任何參數。


    先來實現依次執行,這是最簡單的方式,在類中增加 run 方法,手動調用:



    class VueRouter {

     // ... 其他省略,增加 run 函數


     run(){

       // 把需要依次執行的回調存放在一個隊列中

       let queue = [].concat(

         this.beforeHooks,

         this.afterHooks

       )

       

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

         if(queue(i)) {

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

         }

       }

     }

    }


    // 手動調用


    router.run()

    打印:


    'beforEach'

    'beforeEnter'

    上面把要依次執行的回調函數聚合在一個隊列中執行,并傳入必要的參數,但這樣開發者不能控制是否進行下一步,即便不執行 next 函數,依然會依次執行完隊列的函數。


    改進一下:


    class VueRouter {

     // ... 其他省略,增加 run 函數


     run(){

       // 把需要依次執行的回調存放在一個隊列中

       let queue = [].concat(

         this.beforeHooks,

         this.afterHooks

       )

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

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

          console.log('調用結束');

         })

       })

     }

    }


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

     console.log('beforEach');

     // next()

    })


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

     console.log('beforeEnter');

     next()

    })

    傳入的 next 函數會有調用下一個回調函數的行為,把控制權交給了開發者,調用了 next 函數會繼續執行下一個回調函數;不調用 next 函數,則終止了隊列的執行,所以打印結果是:


    'beforEach'

    上面實現有個弊端,代碼不夠靈活,手動一個個調用,在真實場景中無法確定注冊了多少個回調函數,所以需要繼續抽象成一個功能更強的方法:


    function runQueue (queue, fn, cb) {

     const step = index => {

       // 隊列執行結束了

       if (index >= queue.length) {

         cb()

       } else {

         // 隊列有值

         if (queue[index]) {

           // 傳入隊列中回調,做一些必要的操作,第二個參數是為了進行下一個回調函數

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

             step(index + 1)

           })

         } else {

           step(index + 1)

         }

       }

     }

     // 初次調用,從第一個開始

     step(0)

    }

    runQueue 就是執行隊列的通用方法。


    第一個參數為回調函數隊列, 會依次取出來;

    第二個參數是函數,它接受隊列中的函數,進行一些其他處理;并能進行下個回調函數的執行;

    第三個參數是隊列執行結束后調用。

    知道了這個函數的含義,來使用一下:



    class VueRouter {

     // ... 其他省略,增加 run 函數


     run(){

       // 把需要依次執行的回調存放在一個隊列中

       let queue = [].concat(

         this.beforeHooks,

         this.beforeEnterHooks

       )


       // 接收回到函數,和進行下一個的執行函數

       const iterator = (hook, next) => {

         // 傳給回調函數的參數,第三個參數是函數,交給開發者調用,調用后進行下一個

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

           console.log('執行下一個回調時,處理一些相關信息');

           next()

         })

       }


       runQueue(queue, iterator, () => {


         console.log('執行結束');

         // 執行 afterEach 中的回調函數

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

           fn()

         })

       })

     }

    }

    // 注冊

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

    從上面代碼可以看出來,每次把隊列 queue 中的回調函數傳給 iterator , 用 hook 接收,并調用。

    傳給 hook 必要的參數,尤其是第三個參數,開發者在注冊的回調函數中調用,來控制進行下一步。

    在隊列執行完畢后,依次執行 afterHooks 的回調函數,不傳入任何參數。


    所以打印結果為:


    beforEach

    執行下一個回調時,處理一些相關信息

    beforeEnter

    執行下一個回調時,處理一些相關信息

    執行結束

    afterEach

    以上實現的非常巧妙,再看 Vue-router 源碼這塊的實現方式,相信你會豁然開朗。

    日歷

    鏈接

    個人資料

    藍藍設計的小編 http://www.lzhte.cn

    存檔

    主站蜘蛛池模板: 当雄县| 丁香五月亚洲综合在线国内自拍| 国产绿帽视频大全在线放| 亚洲av无码片在线播放| 91pao强力打造免费高清| 亚洲成a人在线播放www| 色偷偷男人的天堂亚洲av| 国产女人91精品嗷嗷嗷嗷| 天天爽夜夜爽一区二区三区| 国产肉体XXXX裸体784大胆| 亚洲人成网亚洲欧洲无码久久| 久久久国产精品无码一区二区| 精品人妻潮喷久久久又裸又黄 | 丰满少妇内射一区| 最新91精品国产手机| 99久久精品无码一区二区三区| 人妻中文字幕精品一页| A级毛片高清免费视频就| 成人网址在线观看| 久爱免费精品视频在线播放| 亚洲中文字幕第一页在线| 尤物com| 国内精品免费久久久久电影院97| 日韩精品国产专区一区| 在线播放亚洲欧美日韩| 少妇性饥渴videofree| 三级片网站在线观看| 久久人妻少妇久久中文| 国产乱子伦精品视频| 一区二区三区四区在线| 精品少妇大屁股白浆无码| 亚洲毛片一级带毛片基地| 精品国产电影久久九九| 欧美性爱一区二区三区无a| 免费黄色小视频网站| 精品无码一区二区三区电影| 黄色三级片网站| 中文字幕有码无码人妻av蜜桃| 久久久噜噜噜久久久精品| 国产精品%20高清%20尿%20小便%20嘘嘘| 精品一区二区三人妻视频|