vue之vue router

走在前端的大道上

本篇將自己讀過的相關 vue router 文章中,對自己有啓發的章節片段總結在這(會對原文進行刪改),會不斷豐富提煉總結更新。

文章內容 基於vue 2.0

1.vue router如何傳參?

1.1 params、query是什麼?

params:/router1/:id ,/router1/123,/router1/789 //這裏的id叫做params
query:/router1?id=123 ,/router1?id=456 //這裏的id叫做query。
比如:跳轉/router1/:id
<router-link :to="{ name:'router1',params: { id: status}}" >正確</router-link>
<router-link :to="{ name:'router1',params: { id2: status}}">錯誤</router-link>

1.2 html標籤傳參

params、query不設置也可以傳參,params不設置的時候,刷新頁面或者返回參數會丟失

路由界面:

當你使用params方法傳參的時候,要在url後面加參數名,並在傳參的時候,參數名要跟url後面設置的參數名對應。params是路由的一部分,必須要有,否則會導致跳轉失敗或者頁面會沒有內容
如圖片 :id

clipboard.png

clipboard.png

// 上面的router-link傳參,也可以使用編程式導航跳轉
this.$router.push({  name:'router1',params: { id: status ,id2: status3},query: { queryId:  status2 }});
//編程跳轉寫在一個函數裏面,通過click等方法來觸發

query,是拼接在url後面的參數,就沒有這種限制,直接在跳轉裏面用就可以,沒有也沒關係。

使用路由上面的參數

<template>
  <div class="router1">
    <h1>接收參數的路由</h1>
    <h1> params.id:{{ $route.params }}</h1>
    <h1>query.status:{{ $route.query.queryId }}</h1>
    <keep-alive>
      <router-view></router-view>
    </keep-alive>
  </div>
</template>

注意:獲取路由上面的參數,用的是$route,後面沒有r

本節參考文章:vue router 使用params query傳參,以及有什麼區別

1.3 vue this.$router.push()傳參

params 傳參
注意⚠️:patams傳參 ,路徑不能使用path 只能使用name,不然獲取不到傳的數據

this.$router.push({name: 'dispatch', params: {paicheNo: obj.paicheNo}})

取數據:

this.$route.params.paicheNo

query 傳參

this.$router.push({path: '/transport/dispatch', query: {paicheNo: obj.paicheNo}})

取數據:

this.$route.query.paicheNo

2.this.$router 與 this.$route 

在登錄頁完成登錄請求後進行下面的操作 獲取路徑中存放前一個路徑的參數 ,然後跳轉到該頁面

 loginSuccess() {
      const { params: { back } } = this.$route;
      const route = back || { name: 'home' };
      const { name, params, query } = route;
      this.$router.replace({ name, params, query });
    },

在上面這段代碼中出現了兩個我們經常混淆的概念:
我們知道this.$routerrouter實例,可以用來直接訪問路由。我們稱router配置中每一個對象爲一個路由記錄,this.$route是暴露出來用來訪問每個路由記錄的。因此我們獲取參數時使用的是this.$route 跳轉路由時使用的是道this.$router

this.$router.push 與 this.$router.replace

上端代碼中我們使用了replace而不是push來跳轉路由,這兩者的區別是會不會在history中產生記錄。replace不會新增記錄,而是直接替換掉了這條路由記錄。

本節參考文章:vue router+ vuex+ 首頁登錄判斷邏輯

3.路由懶加載

路由懶加載應該是寫大一點的項目都會用的一個功能,只有在使用這個component的時候纔會加載這個相應的組件,這樣寫大大減少了初始頁面 js 的大小並且能更好的利用遊覽器的緩存。

首先,可以將異步組件定義爲返回一個 Promise 的工廠函數 (該函數返回的 Promise 應該 resolve 組件本身):

const Foo = () => Promise.resolve({ /* 組件定義對象 */ })
const Foo = resolve => require(['./Foo.vue'], resolve)
//或者
const Foo = () => import('./Foo');

官網:詳細

4.單頁及多頁應用全局配置404頁面

4.1 SPA的404路由配置

單頁應用配置404頁面,也區分兩種情況:

4.1.1 路由表固定的情況

如果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'
    }
  ],
})
4.1.2 路由表動態生成的情況

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

本項目中動態生成路由採用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 [
  {
    name: '404',
    path: '/404',
    component: () => import('@/views/notFound.vue')
    },
  },
  {
    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)
  })

4.2 多頁應用的404路由配置

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

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

// 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)
  })

本節參考文章:Vue單頁及多頁應用全局配置404頁面實踐

5.後臺系統權限控制

具體實現思路

  1. 創建vue實例的時候將vue-router掛載,但這個時候vue-router掛載一些登錄或者不用權限的公用的頁面。
  2. 當用戶登錄後,獲取用role,將role和路由表每個頁面的需要的權限作比較,生成最終用戶可訪問的路由表。
  3. 調用router.addRoutes(store.getters.addRouters)添加用戶可訪問的路由。
  4. 使用vuex管理路由表,根據vuex中可訪問的路由渲染側邊欄組件。

6.基於路由的動態過渡

<!-- 使用動態的 transition name -->
<transition :name="transitionName">
  <router-view></router-view>
</transition>
// 接着在父組件內
// watch $route 決定使用哪種過渡
watch: {
  '$route' (to, from) {
    const toDepth = to.path.split('/').length
    const fromDepth = from.path.split('/').length
    this.transitionName = toDepth < fromDepth ? 'slide-right' : 'slide-left'
  }
}

動手理解導航守衛(Vue)

Vue動態路由的實現(後臺傳遞路由,前端拿到並生成側邊欄)

手摸手,帶你用vue擼後臺 系列二(登錄權限篇)

vue router原理

前端的路由模式包括了 Hash 模式和 History 模式。
vue-router 在初始化的時候,會根據 mode 來判斷使用不同的路由模式,從而 new 出了不同的對象實例。例如 history 模式就用 HTML5Historyhash 模式就用 HashHistory

vue-router 源碼:前端路由
vue-router 源碼:路由模式

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章