国产精品爱久久久久久久小说,女人扒开腿让男人桶到爽 ,亚洲欧美国产双大乳头,国产成人精品综合久久久久,国产精品制服丝袜无码,免费无码精品黄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://www.dzxscac.cn

            存檔

            主站蜘蛛池模板: 曰批女人视频在线观看| 欧美影视| 国产精品无码无需播放器| 国产成人精品久久一区二区| 久久超碰在线| 大陆精大陆国产国语精品| 2020久久天天躁狠狠躁夜夜| 日本伊人久久| 极品国产在线| 久久av喷潮久久av高清| 国产综合av| 99re热这里只有精品视频| 国产乱码字幕精品高清av | 国产婷婷综合在线视频| 久久九九久精品国产88| 小萝莉末成年一区二区| av午夜福利一片免费看久久| 国产八十老太另类| 中文字幕在线免费视频| 在线观看国产麻豆| 日韩综合无码一区二区| 国产精品自在线拍亚洲另类| 欧美日韩亚洲系列| 久久香综合精品久久伊人| 国产精品成人av电影不卡| 成人免费影院| 黄色小视频网| 成人无码一区二区三区| 午夜一区二区亚洲福利| 久久久久美女| 久久精品99国产精品日本| 亚洲成av人最新无码不卡短片| 在线观看不卡av| 老头糟蹋新婚少妇系列小说| 小泽玛莉亚一区二区视频在线| 国产成人尤物在线视频| 国内自拍小视频| 玩弄放荡人妻少妇系列| 久久久久国色αv免费观看| 九九热九九| 中文在线www|