1. 程式人生 > >Vue.js(五) 路由(vue-router)

Vue.js(五) 路由(vue-router)

官方文件:https://router.vuejs.org/zh/installation.html

一:簡介

Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度整合,讓構建單頁面應用變得易如反掌。包含的功能有:

  • 巢狀的路由/視圖表
  • 模組化的、基於元件的路由配置
  • 路由引數、查詢、萬用字元
  • 基於 Vue.js 過渡系統的檢視過渡效果
  • 細粒度的導航控制
  • 帶有自動啟用的 CSS class 的連結
  • HTML5 歷史模式或 hash 模式,在 IE9 中自動降級
  • 自定義的滾動條行為

路由:就是“頁面”之間跳轉,因Vue.js是單頁應用(single page application,SPA),即元件之間的切換。

二: 宣告式路由< router-link to="/path" >

路由開發步驟:

  1. 開發元件(component)
  2. 配置路由(routes)
  3. 渲染:路由連結(< router-link to="/path">)和路由檢視(< router-view>< /router-view>)

將元件 (component) 對映到路由 (routes),然後告訴 Vue Router哪個連結(< router-link to="/path">) 要在哪裡(< router-view>)來渲染它們。

2.1 Foo.vue

<template>
    <div>
      Foo
    </div>
</template>

<script>
  export default {
    name: 'Foo'
  }
</script>

<style scoped>

</style>

2.2 Bar.vue

$route.params.路徑變數: 用於獲取路由的路徑變數, 就像Java中的@PathVariable一樣。監聽動態路徑引數的變化可以通過watch: { '$route' (to, from) { } }

或者beforeRouteUpdate (to, from, next) { }, 兩者的區別是watch沒有next 引數。

watch: {
  '$route' (to, from) {
    // 對路由變化作出響應...
  }
},
beforeRouteUpdate (to, from, next) {
	next()
}
<template>
    <div>
      Bar {{ this.$route.params.id }}
    </div>
</template>

<script>
  export default {
    name: 'Bar',
    created () {
      this.init()
    },
    beforeRouteUpdate (to, from, next) {
      console.log(to)
      console.log(from)
      console.log(next)
      // 需要呼叫next()才會繼續路由,就像攔截器一樣放開攔截
      next()
      this.init()
    },
    methods: {
      init () {
        console.log('Bar created ' + this.$route.params.id)
      }
    }
  }
</script>

<style scoped>

</style>

2.3 配置路由(src/router/index.js)

關於path,可以使用路徑引數(:引數名)的形式,也可以使用更加複雜的正則表示式。這種稱之為“動態路由”
使用表示式當匹配到多個路徑時優先匹配第一個滿足條件的路徑。

注意:當多個路徑路由到同一個元件時,因為元件會被複用,所以此時對於生命週期鉤子只會呼叫一次。可以通過beforeRouteUpdate函式來監聽路由的變化,在函式體內處理一些邏輯,比如將created的邏輯提取到某個方法中,然後在created和beforeRouteUpdate分別呼叫該方法。

// 匯入vue-router,vue-router需要依賴vue
import Vue from 'vue'
import Router from 'vue-router'

import Foo from '../components/Foo'
import Bar from '../components/Bar'

// 使用vue-router外掛
Vue.use(Router)

// 匯出Router物件,以便被其它檔案(main.js)匯入
export default new Router({
  routes: [
    {
      path: '/foo',
      component: Foo
    },
    {
      path: '/bar/:id',
      name: 'bar',
      component: Bar
    }
  ]
})

2.4 src/mian.js

import Vue from 'vue'
import App from './App'
// 匯入Router
import router from './router'

/* eslint-disable no-new */
// 引用router
new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
})

2.5 App.vue

  • 使用<router-link to="/path">配置頁面跳轉連結,<router-link to="/path">將被解析成<a href="#/path" class="router-link-active">如果路徑匹配成功後還會自動設定class=“router-link-active”。
  • <router-view>用於定義跳轉頁面的模板內容將在哪個地方展示,即跳轉頁面的內容將會把<router-view>標籤替換成具體的模板內容
<template>
  <div id="app">
    Vue Router
    <p>
      <router-link to="/foo">Go to Foo</router-link>
      <router-link to="/bar/1">Go to Bar 1</router-link>
      <router-link :to="{name: 'bar', params: {id: 2}}">Go to Bar 2</router-link>
    </p>
    
    <router-view></router-view>
  </div>
</template>

<script>
  export default {
    name: 'App'
  }
</script>

<style>
  #app {
    font-family: 'Avenir', Helvetica, Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-align: center;
    color: #2c3e50;
    margin-top: 60px;
  }
</style>

在這裡插入圖片描述

三:程式設計式路由this.$router.push(…)

3.1 this.$router.push(…)

使用<router-link>標籤來切換元件稱之為宣告式路由。也可以通過程式設計的方式來呼叫路由器router的push方法來切換元件, 呼叫router.push(...)方法會向 history棧 新增一個新的記錄,所以當用戶點選瀏覽器後退按鈕時,則回到之前的URL。實際上宣告式路由內部也會呼叫router.push(…)方法。

// 新增元件(會將路徑新增到history棧中)
router.push(location, onComplete?, onAbort?)

// 替換元件(不會將路徑新增到history棧中)
router.replace(location, onComplete?, onAbort?)

// 前進或者後退
router.go(n)
  • location : 切換元件的路徑,可以是一個純字串的路徑,或者是一個路徑物件(可以包含元件名稱name、路徑path、引數params、查詢引數query)。

  • onComplete:可選回撥函式,將會在導航成功完成 (在所有的非同步鉤子被解析之後)後回撥。

  • onAbort:可選回撥函式,終止 (導航到相同的路由、或在當前導航完成之前導航到另一個不同的路由)時呼叫。

    // 字串
    router.push('foo')
    
    // 物件
    router.push({ path: 'foo' })
    
    // 命名的路由(注意:params不能與path結合使用)
    // name:是指都會配置路由時的name值
    // 這種方式引數不會追加在路徑後面
    router.push({ name: 'user', params: { userId: 123 }})
    
    // 帶查詢引數,變成 /register?plan=private
    // 這種方式會將引數追加到路徑後面
    router.push({ path: 'register', query: { plan: 'private' }})
    

router.replace跟router.push很像,唯一的不同就是,它不會向 history 新增新記錄,而是跟它的方法名一樣 —— 替換掉當前的 history 記錄。

3.2 router.go(n)

這個方法的引數是一個整數,意思是在 history 記錄中向前或者後退多少步,類似 window.history.go(n)。

// 在瀏覽器記錄中前進一步,等同於 history.forward()
router.go(1)

// 後退一步記錄,等同於 history.back()
router.go(-1)

// 前進 3 步記錄
router.go(3)

// 如果 history 記錄不夠用,那就默默地失敗唄
router.go(-100)
router.go(100)

3.3 使用示例

3.3.1 Foo.vue

<template>
    <div>
      Foo
    </div>
</template>

<script>
  export default {
    name: 'Foo'
  }
</script>

<style scoped>

</style>

3.3.2 Bar.vue

<template>
    <div>
      Bar query: {{ this.$route.query }}
    </div>
</template>

<script>
  export default {
    name: 'Bar',
    created () {
      this.init()
    },
    beforeRouteUpdate (to, from, next) {
      console.log(to)
      console.log(from)
      console.log(next)
      // 需要呼叫next()
      next()
      this.init()
    },
    methods: {
      init () {
        console.log('Bar created ' + this.$route.params.id)
      }
    }
  }
</script>

<style scoped>

</style>

3.3.3 Foobar.vue

<template>
    <div>
      Foobar {{ this.$route.params.id }}
    </div>
</template>

<script>
  export default {
    name: 'Foobar'
  }
</script>

<style scoped>

</style>

3.3.4 src/router/index.js

import Vue from 'vue'
import Router from 'vue-router'

import Foo from '../components/Foo'
import Bar from '../components/Bar'
import Foobar from '../components/Foobar'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/foo',
      component: Foo
    },
    {
      path: '/bar/:id',
      component: Bar
    },
    {
      path: '/foobar',
      name: 'Foobar',
      component: Foobar
    }
  ]
})

3.3.5 App.vue

<template>
  <div id="app">
    Vue Router
    <p>
      <button @click="jumpFoo">字串foo</button> <br>
      <button @click="$router.push({path: 'foo'})">物件{path: 'foo'}</button> <br>
      <button @click="$router.push({name: 'Foobar', params:{id: 1}})">命名的路由 {name: '', params: {id: 1}}"</button> <br>
      <button @click="$router.push({path: '/bar/666', query:{age: 2}})">帶查詢引數<{path: '', query: {}}</button> <br>

      <button @click="$router.go(-1)">後退一步</button> <br>
    </p>

    <router-view></router-view>
  </div>
</template>

<script>
  export default {
    name: 'App',
    methods: {
      jumpFoo() {
        this.$router.push('foo', function () {
          console.log('onComplete: 跳轉完成')
        }, function (err) {
          console.log('onAbort')
        })
      }
    }
  }
</script>

<style>
  #app {
    font-family: 'Avenir', Helvetica, Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-align: center;
    color: #2c3e50;
    margin-top: 60px;
  }
</style>

在這裡插入圖片描述

四:導航守衛

導航守衛(導航的生命週期):用於監聽路由發生變化的各個生命週期。可以在多個地方來監聽路由的變化,如全域性的, 單個路由獨享的, 或者元件級的。

  • router.beforeEach(to, from, next) => { }) 全域性前置守衛
    • to : Route型別,即將要進入的目標路由物件。
    • from: Route型別,當前導航正要離開的路由物件。
    • next:Function型別,用於決定接下來如何導航,如進行下一個鉤子、 中斷當前導航、跳轉到其它地址等。確保要呼叫 next 方法,否則鉤子就不會被 resolved。
      • next(): 進行管道中的下一個鉤子。如果全部鉤子執行完了,則導航的狀態就是 confirmed (確認的)。
      • next(false): 中斷當前的導航。如果瀏覽器的 URL 改變了 (可能是使用者手動或者瀏覽器後退按鈕),那麼 URL 地址會重置到 from 路由對應的地址。
      • next(’/’) 或者 next({ path: ‘/’ }): 跳轉到一個不同的地址。當前的導航被中斷,然後進行一個新的導航。你可以向 next 傳遞任意位置物件,且允許設定諸如 replace: true、name: ‘home’、redirect 之類的選項以及任何用在 router-link 的 to prop 或 router.push 中的選項。
      • next(error): (2.4.0+) 如果傳入 next 的引數是一個 Error 例項,則導航會被終止且該錯誤會被傳遞給 router.onError() 註冊過的回撥。
  • beforeEnter: (to, from, next) => { } 路由獨享的守衛, 配置在路由中
  • beforeRouteEnter(to, from, next) { } 元件內的守衛,在元件內部使用,在渲染該元件的對應路由被 confirm 前呼叫
  • beforeRouteUpdate (to, from, next) { } 元件內的守衛,在元件內部使用,在當前路由改變,但是該元件被複用時呼叫,舉例來說,對於一個帶有動態引數的路徑 /foo/:id,在 /foo/1 和 /foo/2 之間跳轉的時候,
  • beforeRouteLeave (to, from, next) { } 元件內的守衛,在元件內部使用,導航離開該元件的對應路由時呼叫。

完整的導航解析流程:

  1. 導航被觸發。
  2. 在失活的元件裡呼叫離開守衛。
  3. 呼叫全域性的 beforeEach 守衛。
  4. 在重用的元件裡呼叫 beforeRouteUpdate 守衛 (2.2+)。
  5. 在路由配置裡呼叫 beforeEnter。
  6. 解析非同步路由元件。
  7. 在被啟用的元件裡呼叫 beforeRouteEnter。
  8. 呼叫全域性的 beforeResolve 守衛 (2.5+)。
  9. 導航被確認。
  10. 呼叫全域性的 afterEach 鉤子。
  11. 觸發 DOM 更新。
  12. 用建立好的例項呼叫 beforeRouteEnter 守衛中傳給 next 的回撥函式。

使用示例

App.vue

<template>
  <div id="app">
    <button @click="$router.push('/foo')">foo</button> <br>
    <button @click="$router.push('/bar')">bar</button> <br>

    <router-view></router-view>
  </div>
</template>

<script>
  export default {
    name: 'App',
  }
</script>

src/main.js 全域性監聽路由變化

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
import ElementUI from 'element-ui'


Vue.config.productionTip = false

Vue.use(ElementUI)

router.beforeEach((to, from, next) => {
  console.log('全域性前置守衛beforeEach')
  console.log(to)
  console.log(from)
  console.log('------------------')
  next()
})

router.afterEach((to, from) => {
  console.log('全域性後置鉤子afterEach')
  console.log(to)
  console.log(from)
  console.log('------------------')
})

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
})

src/router/index.js 單個路由的導航監聽

import Vue from 'vue'
import Router from 'vue-router'

import Foo from '../components/Foo'
import Bar from '../components/Bar'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/foo',
      component: Foo,
      beforeEnter: (to, from, next) => {
        console.log('路由獨享的守衛beforeEnter')
        console.log(to)
        console.log(from)
        console.log('------------------')
        next()
      }
    },
    {
      path: '/bar',
      component: Bar
    }
  ]
})

Foo.vue 元件內部導航路由的監聽

<template>
    <div>
      Foo 路由守衛
    </div>
</template>

<script>
  export default {
    name: 'Foo',
    beforeRouteEnter (to, from, next) {
      console.log('beforeRouteEnter')
      console.log(to)
      console.log(from)
      console.log('------------------')
      next()
    },
    beforeRouteUpdate (to, from, next) {
      console.log('beforeRouteUpdate')
      console.log(to)
      console.log(from)
      console.log('------------------')
      next()
    },
    beforeRouteLeave (to, from, next) {
      const answer = window.confirm('你確定要離開嗎?')
      if (answer) {
        console.log('beforeRouteLeave')
        console.log(to)
        console.log(from)
        console
            
           

相關推薦

Vue.js() 路由(vue-router)

官方文件:https://router.vuejs.org/zh/installation.html 一:簡介 Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度整合,讓構建單頁面應用變得易如反掌。包含的功能有: 巢狀的路由/視圖

Vue.js搭建路由報錯 router.map is not a function

錯誤: 出現問題原因:2.0已經沒有map這個方法了,只有1.0相容該方法。 解決方法: (1)方法1:使用命令npm install [email protected]相容1.0版本vu

vue教程()--路由router介紹

一、html頁面中如何使用 1、引入 vue-router.js 2、安裝外掛 Vue.use(VueRouter) 3、建立路由物件   var router = new VueRouter({     // 4、配置路由     routes:[{       path:'/login',

Vue.js系列之vue-router(上) (轉載自向朔1992)

app 指定 路徑和 其他 發現 掛載 我只 router mine 概述 Vue非常適用於實踐單頁面應用程序也就是平時大家說的比較多的SPA(single page application),這點應該了解過Vue的應該都知道吧。一般的單頁面應用是基於路由或頁面之間的鏈接來

Vue.js 生態之vue-router

onerror vue 重定向 跳轉 圖片 clas query code 傳遞 vue-router是什麽~~ vue-router是Vue的路由系統,定位資源的,我們可以不進行整頁刷新去切換頁面內容。 vue-router的安裝和基本配置 vue-rout

vue重新整理當前路由router-view 複用元件時不重新整理的3種解決方案總結

vue-router是Vue.js官方的路由外掛,它和vue.js是深度整合的,適合用於構建單頁面應用。vue的單頁面應用是基於路由和元件的,路由用於設定訪問路徑,並將路徑和元件對映起來。傳統的頁面應用,是用一些超連結來實現頁面切換和跳轉的。在vue-router單頁面應用中,則是路徑之間的切換,也

vue.js通過路由跳轉傳參,重新整理頁面引數丟失

問題:vue.js路由跳轉,跳轉頁面重新整理後引數丟失,沒有資料,怎麼解決?? 出現的情況:從新聞列表頁面進入某一條新聞得詳情頁,需要在路由跳轉時給詳情頁面傳送該條新聞得ID,然後詳情頁獲取ID想後臺請求資料將內容展示,還有商品詳情頁等等~ 下面寫了一個小例子,是模擬專案的新聞列表和詳情頁,

2018年11月10日 關於Vue.js生態之Vue-router and 傳參方式

關於router的用法 //在html中的相關程式碼 <div id="app"> <div> <router-link to="/">首頁</router-link> //<router-link>是Vue-route

Vue.js框架--路由模組化(二十六)

主要操作技能:   1>建立資料夾\router.js檔案      2>寫入相關路由配置 router.js import Vue from 'vue' //0. 使用路由 import VueRouter from 'vue-

Vue.js路由系統

Vue.js生態之vue-router vue-router是什麼? vue-router是Vue的路由系統,定位資源的,我們可以不進行整頁重新整理去切換頁面內容。 vue-router的安裝與基本配置 vue-router.js 可以下載 也可以用cdn,基本配置資訊看如下程式碼 // ht

Vue.js框架--路由程式設計式的導航 和History 模式(十九)

主要操作技能: 一、程式設計式的導航        除了使用 <router-link> 建立 a 標籤來定義導航連結,    我們還可以藉助 router 的例項方法,通過編寫程式碼來實現   點選 <router-link :to="..."&g

2018年11月10日 關於Vue.js生態之Vue-router and 傳參方式

關於router的用法 //在html中的相關程式碼 <div id="app"> <div> <router-link to="/">首頁</router-link> //<router-link&

深入解析Vue.js專案API、Router配置拆分實踐

前後端分離開發方式前端擁有更高的控制權 隨著前端框架技術的飛速發展,Router這個概念也被迅速普及到前端專案中,在早期前後的沒有分離的時期下,並沒有明確的路由概念,前端頁面跳轉大多是通過後端進行請求轉發的,比如在Spring MVC專案中,進行一個頁面跳轉如下(畫紅線部分):

Vue.js動態路由間切換回到頂部

方案1 使用官方的滾動行為,但是必須開啟HTML5 history 模式,開啟HTML5 history 模式需要後端進行一些配置; 對於所有路由導航,簡單地讓頁面滾動到頂部: scrollBehavior (to, from, savedPosition) { return { x

vue】動態路由vue-router 動態載入

有時系統需要根據使用者的許可權來動態載入路由~vue-router有提供給我們一個 addRoutes() 方法,但這個方法只有2.2.0以上版本支援。下面我們看下具體寫法: var router =

Vue.js系列之vue-router(中)(4)

說明: 我們專案現在用的是:vue2.0 + vue-cli + webpack + vue-router2.0 + vue-resource1.0.3 如果大家在實踐的過程中與本文所說的內容有較大區別的話看看是不是版本問題。 本文是一系列文章,在我對V

vue.js 初次路由顯示設定

①設定 path 為 ‘/’ const router= new VueRouter({ routes:[ {path:'/',name:'home',component:Home}, //頁面第一顯示的元件 {path:'/

Vue.js系列之vue-router(下)(5)

說明: 我們專案現在用的是:vue2.0 + vue-cli + webpack + vue-router2.0 + vue-resource1.0.3 如果大家在實踐的過程中與本文所說的內容有較大區別的話看看是不是版本問題。 本文是一系列文章,在我對V

vue.js 二級路由/三級路由

為什麼要用二級和三級路由? 當專案中 有多個 <router-view> 時,就必須使用分級路由; 如果路由不分級,又有多個 <router-view> ,全部都是定義為一級路由,那麼專案中的  <router-view> 的內容顯示就

Vue.js框架路由練習

/*定義元件*/ const home = { template: '#home', props:{ info:Array,