VueRouter進階02

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

完整的導(dǎo)航解析流程

  1. 導(dǎo)航被觸發(fā)
  2. 在失活的組件里調(diào)用離開守衛(wèi)beforeRouteLeave
  3. 調(diào)用全局beforeEach守衛(wèi)
  4. 調(diào)用重用組件中beforeRouteUpdate守衛(wèi)(2.2+)
  5. 調(diào)用路由配置里beforeEnter守衛(wèi)
  6. 解析異步路由組件
  7. 在被激活的組件里調(diào)用beforeRouteEnter守衛(wèi)
  8. 調(diào)用全局的beforeResolve守衛(wèi)(2.5+)
  9. 導(dǎo)航被確認
  10. 調(diào)用全局的afterEach鉤子
  11. 觸發(fā)DOM更新
  12. 用創(chuàng)建好的實例調(diào)用beforeRouteEnter守衛(wèi)中傳給next的回調(diào)函數(shù)

全局守衛(wèi)

const router = new VueRouter({...});
router.beforeEach(function (to,from,next) {})
  1. to是即將進入的路由對象,$route
  2. from是正要離開的路由
  3. next方法
  • next()進入管道中下一個守衛(wèi),如果執(zhí)行完了,就是導(dǎo)航確認
  • next(false)中端當前的導(dǎo)航
  • next('/')跳轉(zhuǎn)到另一個地址
  • next(error),當error是Error實例時,觸發(fā)router.onError()

全局解析守衛(wèi)

調(diào)用的時機不同,在所有組件內(nèi)守衛(wèi)和異步路由組件被解析之后

組件守衛(wèi)

const foo = {
    template: '',
    beforeRouteEnter: function (to,from,next) {

    },
    beforeRouteUpdate: function (to,from,next) {

    },
    beforeRoteLeave: function (to,from,next) {

    }
}
  1. beforeRouteEnter中不能訪問 this
  2. 傳遞一個回調(diào)給next,在導(dǎo)航確認的時候執(zhí)行,通過vm實例訪問組件
beforeRouteEnter (to, from, next) {
  next(vm => {
    // 通過 `vm` 訪問組件實例
  })
}

路由獨享的守衛(wèi)

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

路由元信息

為路由添加路由元信息,案例中可以使用它來判斷,該頁面是否需要身份確認

  1. /foo/bar將會匹配父路由記錄和子路由記錄,在$route.matched數(shù)組中可以查詢到
  2. 不僅組件中$route是路由信息對象,各個守衛(wèi)中to也是路由信息對象
  3. 在各個守衛(wèi)中,可以查看匹配的路由的meta,確認登陸該路由是否需要特殊的條件,比如需要登陸狀態(tài)才可以訪問
// 設(shè)置 路由元 信息,讓導(dǎo)航到該連接的時候進行身份確認

const router = new VueRouter({
    routes: [
        {
            path: '/foo',
            compoent: Foo,
            children: [
                {
                    path: 'bar',
                    component: Bar,
                    meta: { requiresAuth: true }
                }
            ]
        }
    ]
});
// 路由全局注冊,當跳轉(zhuǎn)時,確認用戶是否跳轉(zhuǎn)
// to 是將要到達的路由對象,其中`$route.matched`存儲著匹配的所有路由記錄
router.beforeEnter((to,from,next) => {
    if (to.matched.some(record => record.meta.requiresAuth)) {
        if (!auth.loggedIn()) {
            next({
                path: '/login',
                query: {
                    redirect: to.fullPath
                }
            });
        }else {
            next();
        }
    }else {
        next();
    }
});

過渡效果

router-view添加過渡效果

<transition>
  <router-view></router-view>
</transition>

單個路由過渡效果,在每個路由對應(yīng)的模板內(nèi)添加transition。這樣,每個路由都有自己的過渡效果

const Foo = {
  template: `
    <transition name="slide">
      <div class="foo">...</div>
    </transition>
  `
}

const Bar = {
  template: `
    <transition name="fade">
      <div class="bar">...</div>
    </transition>
  `
}

重點。根據(jù)路由路徑的不同,通過動態(tài)綁定,添加不同的過渡效果

<transition :name="transitionName">
  <router-view></router-view>
</transition>
// 父組件中監(jiān)聽 $route
watch: {
    '$route' (to,from) {
        const toDepth = to.path.split('.').length;
        const fromDepth = from.path.split('.').length;
        this.trasitionName = toDepth < fromDepth ? 'slide-right' : 'slide-left' 
    }
}

數(shù)據(jù)獲取

數(shù)據(jù)獲取可以下導(dǎo)航完成之前,也可以在導(dǎo)航完成之后

  1. 關(guān)于導(dǎo)航時,數(shù)據(jù)獲取,有一個狀態(tài)loading

導(dǎo)航完成后獲取數(shù)據(jù)

// 通過監(jiān)聽路由的變化,獲取數(shù)據(jù)
export default {
    created: function () {
        // 組件鉤子函數(shù),當組件創(chuàng)建完成之后
        this.fetchData();
    },
    watch: {
        '$route': 'fetchData'
    },
    methods: {
        fetchData () {
            this.error = this.post = null
            this.loading = true
            // 下邊是一個自定義獲取數(shù)據(jù)的方法,可以自己寫
            getPost(this.$route.param.id,(err,post)=>{
                // 數(shù)據(jù)拿回來之后可以不是loading狀態(tài)了
                this.loading = false;
                if (err) {
                    this.error = err.toString()
                } else {
                    this.post = post
                }
            });
        }
    }
}

在導(dǎo)航前獲取數(shù)據(jù)

// 根據(jù)組件的鉤子函數(shù)

export default {
  data () {
    return {
      post: null,
      error: null
    }
  },
  beforeRouteEnter (to, from, next) {
    getPost(to.params.id, (err, post) => {
      next(vm => vm.setData(err, post))
    })
  },
  // 路由改變前,組件就已經(jīng)渲染完了
  // 邏輯稍稍不同
  beforeRouteUpdate (to, from, next) {
    this.post = null
    getPost(to.params.id, (err, post) => {
      this.setData(err, post)
      next()
    })
  },
  methods: {
    setData (err, post) {
      if (err) {
        this.error = err.toString()
      } else {
        this.post = post
      }
    }
  }
}

建議,在獲取數(shù)據(jù)的時候可以進行進度條顯示。如果數(shù)據(jù)獲取失敗,要展示一些全局的錯誤提醒。

滾動行為

這個行為只有在html5 History模式下才可以用,當跳轉(zhuǎn)頁面的時候,頁面滾動某處

const router = new VueRouter({
    routes,
    scrollBehavior: function (to,from,savedPosition) {
        // 第三個參數(shù)只有當使用瀏覽器的前進后退鍵時,才有
          if (savedPosition) {
            return savedPosition
        } else {
            return { x: 0, y: 0 }
            // 或者跳轉(zhuǎn)到錨點
            return {
                selector: to.hash
            }
        }
    }
})
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,057評論 25 709
  • 用Vue.js + vue-router創(chuàng)建單頁應(yīng)用,是非常簡單的,基本是這樣的: 組件 → 路由 → 渲染地方 ...
    阿go閱讀 1,450評論 0 0
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,568評論 19 139
  • Vue-Router簡介 Vue-Router是Vue.js官方維護的路由插件,同時也是官方推薦的路由插件。它與V...
    SunnySky_閱讀 872評論 0 1
  • 用行動去實現(xiàn)自己的derm Hello! 感謝大家在百忙之中抽出時間來參加這次南充趁早讀書會的線下聚會,好久不見,...
    初心夏至閱讀 809評論 0 3

友情鏈接更多精彩內(nèi)容