国产精品美女久久久浪潮AV,国产精品三级一二三区,久久精品国产一区二区小说 ,依依成人影视国产精品,全部无卡免费的毛片在线看,日本一区二区三深夜不卡,国产精品女同一区二区久久,国产精品夜色一区二区三区

        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://m.shtzxx.cn

        存檔

        主站蜘蛛池模板: 中国老太婆bb无套内射| 昆明市| 人人妻人人澡人人爽欧美精品| 国产精品久久国产精品99| 一个吃奶两个添下面h| 97人妻人人做人碰人人爽| 国产白嫩美女在线观看| 精品国产亚洲一区二区三区在线观看 | xxxxbbbb欧美残疾人| 亚洲熟熟妇xxxx| 久久精品夜色国产亚洲av| 国产熟妇的荡欲午夜视频| 久久天天躁狠狠躁夜夜av浪潮| 日本欧美视频在线观看| 国产成人午夜精品久久久久久 | 精品国产福利一区二区| 日韩在线视频观看免费网站| 在线a毛片免费视频观看| 东乡族自治县| 国产内射性高湖| 亚洲精品久久区二区三区蜜桃臀| 狠狠干狠狠爱| 国产免费一区二区三区不卡| 少妇乳大丰满在线播放| 空之色| 亚洲精品国产av天美传媒| japan丰满人妻hd| 99精产国品一二三产区| 平利县| 色av永久无码影院av| 日本丰满熟妇videossexhd| 伦理资源站| 狠狠人妻久久久久久综合九色| 午夜无遮挡男女啪啪免费软件| 免费精品99久久国产综合精品| 国产精品久久..4399| 亚洲男同帅gay片在线观看| 绥芬河市| 欧美性xxxxx极品少妇| 国产精品igao视频| 国产免费又色又爽粗视频|