學習vue-router

vue-router 基礎

  1. 做用: 經過管理URL,實現URL和組件的對應和經過URL進行組件之間的切換
  2. 其餘概念:

單頁應用:加載單個HTML頁面,並在用戶與應用程序交互時,動態該頁面vue

  1. 使用步驟:vue-router

    • 安裝模塊: npm install vue-router --savenpm

    • 引入模塊: import VueRouter from 'vue-router'編程

    • 做爲插件:Vue.use(VueRoter)數組

    • 建立路由實例對象:瀏覽器

      new VueRouter({
          // 匹配相關參數
      })
      
      複製代碼
    • 注入vue選項參數: new VueRouter({ router })bash

    • 告訴路由渲染的位置: 異步

    • 引入組件,匹配組件URL:<router-link v-bind:to="path"> 內容 </router-link>ide

    具體頁面代碼:函數

    import Vue from 'vue'
    // 1. 安裝vue-router後引入vue-router模塊
    import Router from 'vue-router'
    import Index from '@/views/index'
    
    // 2. 做爲插件
    Vue.use(Router)
    
    // 3. 建立路由實例對象
    export default new Router({
    mode : 'history',// 歷史模式
    linkActiveClass: 'is-active', // 活動樣式
    scrollBehavior(to, from, savePosition){
        // 點擊瀏覽器的前進後退或切換導航時觸發
        console.log(to); // 要進入的目標對象  要去哪
        console.log(from); // 離開的目標  從哪來
        console.log(savePosition); // 記錄滾動條位置,點擊前進後退時觸發
    
        // if(savePosition){
        //   return savePosition; // 滾動條位置不是0時,便可保存位置
        // }else{
        //   return {x:0,y:0} 
        // }
    
        if(to.hash){
        return {
            selector: to.hash
        }
        }
    },
    routes: [
        {
        path: '/',
        name: 'Index',
        component: Index
        }
    ]
    })
    
    
    複製代碼

    動態路由匹配

    動態路徑參數 以冒號開頭

    {
        path:'/user/:id',component: User
    }
    複製代碼

    一個「路徑參數」使用冒號:標記。當匹配到一個路由時,參數會被設置到this.$route.params,能夠在每一個組件內使用。
    也能夠在一個路徑張紅設置多段「路徑參數」,對應的值都會設置到$route.params

    • 捕獲全部路由或404 Not found路由 {path: '*'}

    當使用了一個通配符時,$route.params內會自動添加一個名爲pathMath參數。


編程式的導航

除了使用<router-link></router-link>建立a標籤來定義導航連接,還能夠經過編寫代碼來實現。

router.push(location, onComplete?, onAbort?)
注意:在vue實例內部,能夠經過$router訪問路由實例

想要導航到不一樣的URL,則使用router-push方法。這個方法會向history棧添加一個新的記錄

該方法的參數能夠是一個字符串路徑,或者一個描述地址的對象

// 字符串
    router.push('home')

    // 對象
    router.push({ path: 'home' })

    // 命名的路由
    router.push({ name: 'user', params: { userId: '123'} })

    // 帶查詢參數,變成 /register?plan=private
    router.push({ path: 'register', query: { plan: 'private' } })
複製代碼

router.replace(location, onComplete?, onAbort?) :替換掉當前的history記錄

router.go(n) 在history記錄中向前或者後退多少步,相似window.history.go(n)


命名視圖

<router-view name='slider'></router-view>
路由視圖<router-view>通常的默認命名爲default,當想要匹配不一樣的視圖時,即可以經過命名,找到相應的視圖組件。name值的匹配


## 重定向和別名 ``` const router = new VueRouter({ routes: [ {path: '/a', redirect: '/b'} ] }) ``` 或者是動態返回重定向目標:
const router = new VueRouter({
    routes: [
        {path:'/a',redirect: to =>{
            // 方法接收 目標路由 做爲參數
            // return 重定向的 字符串路徑/路徑對象
        }}
    ]
})

複製代碼

注意導航守衛並無應用在跳轉路由上,而僅僅應用在其目標上。


路由組件傳參

在組件中使用$route會使之與其對應路由造成高度耦合,從而使組件只能在某些特定的URL上使用,限制了靈活性。

使用props將組件和路由解耦: 取代與$route的高耦合

const User = {
    template: '<div>User {{ $route.params.id }}</div>'
    }
    const router = new VueRouter({
    routes: [
        { path: '/user/:id', component: User }
    ]
    })
複製代碼

經過 props 解耦

const User = {
  props: ['id'],
  template: '<div>User {{ id }}</div>'
}
const router = new VueRouter({
  routes: [
    { path: '/user/:id', component: User, props: true },

    // 對於包含命名視圖的路由,你必須分別爲每一個命名視圖添加 `props` 選項:
    {
      path: '/user/:id',
      components: { default: User, sidebar: Sidebar },
      props: { default: true, sidebar: false }
    }
  ]
})

複製代碼

三大模式

  • 布爾模式

若是props 被設置爲true,route.params將會被設置爲組件屬性

  • 對象模式

若是props是一個對象,它會被按原樣設置爲組件屬性。當props是靜態的時候有用

  • 函數模式

能夠建立一個函數返回props。這樣就能夠將參數轉換成另外一種類型,將靜態值與基於路由的值結合等。

儘量保持props函數爲無狀態的,由於它只會在路由發生變化時起做用。若是須要狀態來定義props,請使用包裝組件,這樣vue才能夠對狀態變化作出反應

導航守衛

組件內的守衛

const Foo = {
  template: `...`,
  beforeRouteEnter (to, from, next) {
    // 在渲染該組件的對應路由被 confirm 前調用
    // 不!能!獲取組件實例 `this`
    // 由於當守衛執行前,組件實例還沒被建立
  },
  beforeRouteUpdate (to, from, next) {
    // 在當前路由改變,可是該組件被複用時調用
    // 舉例來講,對於一個帶有動態參數的路徑 /foo/:id,在 /foo/1 和 /foo/2 之間跳轉的時候,
    // 因爲會渲染一樣的 Foo 組件,所以組件實例會被複用。而這個鉤子就會在這個狀況下被調用。
    // 能夠訪問組件實例 `this`
  },
  beforeRouteLeave (to, from, next) {
    // 導航離開該組件的對應路由時調用
    // 能夠訪問組件實例 `this`
  }
}

複製代碼

注意: beforeRouteEnter守衛不能訪問this,由於守衛在導航確認前被調用,所以即將登場的新組件還沒被建立。 不過能夠經過一個回調next來訪問組件實例。在導航被確認的時候執行回調,而且把組件實例做爲回調方法的參數:

beforeRouteEnter (to, from, next) {
  next(vm => {
    // 經過 `vm` 訪問組件實例
  })
}
複製代碼

注意: beforeRouteEnter是支持給next傳遞迴調的惟一守衛。對於 beforeRouteUpdate 和 beforeRouteLeave 來講,this 已經可用了,因此不支持傳遞迴調,由於沒有必要了

beforeRouteUpdate (to, from, next) {
    // just use `this`
    this.name = to.params.name
    next()
    }

複製代碼

這個離開守衛一般用來禁止用戶在還未保存修改前忽然離開。該導航能夠經過 next(false) 來取消。

beforeRouteLeave (to, from , next) {
  const answer = window.confirm('Do you really want to leave? you have unsaved changes!')
  if (answer) {
    next()
  } else {
    next(false)
  }
}

複製代碼

完整的導航解析流程

  1. 導航被觸發
  2. 在失活的組件裏調用離開守衛。
  3. 調用全局的beforeEach守衛
  4. 在重用的組件裏調用beforeRouteUpdate
  5. 在路由配置裏調用beforeEnter
  6. 解析異步路由組件
  7. 在被激活的組件裏調用beforeRouteEnter
  8. 調用全局的beforeResolve守衛
  9. 導航被確認
  10. 調用全局的afterEach鉤子
  11. 觸發DOM更新
  12. 用建立好的實例調用beforeRouteEnter守衛中傳給next的回調函數

路由元信息

一個路由匹配到的全部路由記錄會暴露爲$route對象(還有在導航守衛中的路由對象)的$route.matched數組。所以,咱們須要遍歷$route.matched來檢查路由記錄中的meta字段

下面例子展現在全局導航守衛中檢查元字段:

router.beforeEach((to, from, next) => {
  if (to.matched.some(record => record.meta.requiresAuth)) {
    // this route requires auth, check if logged in
    // if not, redirect to login page.
    if (!auth.loggedIn()) {
      next({
        path: '/login',
        query: { redirect: to.fullPath }
      })
    } else {
      next()
    }
  } else {
    next() // 確保必定要調用 next()
  }
})
複製代碼

數據獲取

  • 導航完成以後獲取:先完成導航,而後在接下來的組件生命週期鉤子中獲取數據。在數據獲取期間顯示「加載中」之類的指示。
  • 導航完成以前獲取:導航完成前,在路由進入的守衛中獲取數據,在數據獲取成功後執行導航。

導航完成後獲取數據

立刻導航和渲染組件,而後在組件的created鉤子中獲取數據。獲取數據期間會展現loading狀態,能夠在不一樣視圖間展現不一樣的loading狀態。

相關文章
相關標籤/搜索