Vue單頁及多頁應用全局配置404頁面實踐

這篇文章也發在個人博客,歡迎圍觀😄html

寫在前面

先後端分離後,控制路由跳轉的責任轉移到了前端,後端只負責給前端返回一個html文檔以及提供各類接口。下面咱們用做例子的兩個項目,均採用vue做爲基礎框架,一個是SPA應用,另外一個是多頁應用,均由前端進行路由控制及渲染的。前端

整體思路

不管單頁仍是多頁,個人實現思路是整體配置404頁面的思路就是在前端路由表中添加一個path: '/404'的路由,渲染相應的404頁面。同時,配置一個規則,當在用戶可訪問的路由表中的全部路由都沒法匹配的時候,自動跳轉重定向至該404頁面。下面來講一下針對單頁和多頁,我不一樣的實現方式。vue

SPA的404路由配置

單頁應用配置404頁面,也區分兩種狀況:vue-router

路由表固定的狀況

若是SPA的路由表是固定的,那麼配置404頁面就變得很是的簡單。只須要在路由表中添加一個路徑爲404的路由,同時在路由表的最底部配置一個路徑爲*的路由,重定向至404路由便可。後端

(因爲路由表是由上至下匹配的,必定要將任意匹配規則至於最底部,不然至於此路由規則下的路由將所有跳轉至404,沒法正確匹配。)數組

// router.js
export default new Router({
  mode: 'history',
  routes: [
    // ...
    {
      name: '404',
      path: '/404',
      component: () => import('@/views/notFound.vue')
    },
    {
      path: '*',    // 此處需特別注意至於最底部
      redirect: '/404'
    }
  ],
})
複製代碼

路由表動態生成的狀況

路由表是動態生成的狀況下,也就是說路由表分爲兩部分,一部分爲基礎路由表,另外一部分是須要根據用戶的權限信息動態生成的路由表。框架

本項目中動態生成路由採用vue-router自帶的addRoutes方法,該方法是會將新的路由規則在原路由表數組的尾部注入的。因爲任意匹配重定向至404頁面的規則必須至於路由表的最底部,因此此處我將重定向至404頁面的規則抽出,在動態路由注入後,再注入重定向規則,以確保該規則至於路由表最底部。前後端分離

// router.js
export default new Router({
  mode: 'history',
  routes: [
    // ...
    {
      name: '404',
      path: '/404',
      component: () => import('@/views/notFound.vue')
    },
    // ...other codes
  ],
})

複製代碼
// notFoundRouterMap.js

export default [
  {
    path: '*',
    redirect: '/404'
  }
]
複製代碼
// main.js

//...other codes
router.beforeEach((to, from, next) => {
  new Promise((resolve, reject) => {
    if (getCookie(tokenName)) {
      if (!getInfo()) {
        Promise.all([store.dispatch('getBasicInfo'), store.dispatch('getUserDetail')]).then(res => {
          store.dispatch('GenerateRoutes', { roles }).then(() => { 
          // 根據用戶權限生成可訪問的路由表
            router.addRoutes(store.getters.addRouters) // 動態添加可訪問路由表
            router.addRoutes(NotFoundRouterMap) // 添加404及重定向路由規則
            resolve({ ...to, replace: true }) // 從新加載一次路由,讓路由表更新成功後走下面else的判斷
          })
          
        })
      } else {
        // ...other codes
      }
    } else {
      window.location.href = '/login.html'
    }
  }).then(res => {
    if (res) {
      next(res)
    } else {
      next()
    }
  }).catch(err => {
    new Error(err)
    next(false)
  })

複製代碼

多頁應用的404路由配置

多頁應用區別於SPA的不一樣點是每一個頁面有本身的一套路由,而且每一個頁面可能有本身的一套404頁面風格,固然也可能沒有。這時候,就不能再採用動態添加路由規則的方法了。post

我採用的方案是在全局導航守衛beforeEach中對路由匹配的狀況進行判斷,這時候就須要用到vue導航守衛中的matched數組了。若是沒有一個匹配上的,那麼就重定向至404頁面。固然,這個404頁面也單獨設置爲一個頁面。ui

// permission.js

//...other codes
router.beforeEach((to, from, next) => {
  new Promise((resolve, reject) => {
    // ...other codes
  }).then(res => {
    if (!to.matched.length) {
        window.location = '/error.html#/404'
        return
      } 
    if (res) {
      next(res)
    } else {
      next()
    }
  }).catch(err => {
    new Error(err)
    next(false)
  })

複製代碼

這個方案就容許每一個頁面有本身的404頁面路由規則,而且爲沒有配置404頁面的路由統一配置了默認的404頁面,感受仍是比較友好的。

最後

這是本人開發過程當中使用的方案,若是有更好的方法,請不吝告知,謝謝!

在作這個實踐的時候,借鑑了很多兄弟的文章,在此列出,以表感謝!

  1. 基於Vue2.0實現後臺系統權限控制
  2. 用addRoutes實現動態路由
  3. how to create a 404 component in vuejs using vue-router
相關文章
相關標籤/搜索