Vue Router詳細教程

說故事的五公子發表於2020-07-31

1.什麼是路由

1.1路由簡介

說起路由你想起了什麼?路由是一個網路工程裡面的術語。

路由(routing)就是通過互聯的網路把資訊從源地址傳輸到目的地址的活動。 --- 維基百科

額,啥玩意? 沒聽懂。在生活中,我們有沒有聽說過路由的概念呢? 當然了,路由器嘛。路由器是做什麼的? 你有想過嗎?路由器提供了兩種機制: 路由和轉送。路由是決定資料包從來源到目的地的路徑。轉送將輸入端的資料轉移到合適的輸出端。路由中有一個非常重要的概念叫路由表。路由表本質上就是一個對映表,決定了資料包的指向。

1.2後端路由階段

早期的網站開發整個HTML頁面是由伺服器來渲染的。伺服器直接生產渲染好對應的HTML頁面,返回給客戶端進行展示。但是,一個網站這麼多頁面伺服器如何處理呢?

一個頁面有自己對應的網址,也就是URL。URL會傳送到伺服器,伺服器會通過正則對該URL進行匹配,並且最後交給一個Controller進行處理。Controller進行各種處理,最終生成HTML或者資料,返回給前端。這就完成了一個IO操作。

上面的這種操作,就是後端路由。當我們頁面中需要請求不同的路徑內容時,交給伺服器來進行處理,伺服器渲染好整個頁面,並且將頁面返回給客戶頓。這種情況下渲染好的頁面,不需要單獨載入任何的js和css,可以直接交給瀏覽器展示,這樣也有利於SEO的優化。

後端路由的缺點:

一種情況是整個頁面的模組由後端人員來編寫和維護的。另一種情況是前端開發人員如果要開發頁面,需要通過PHP和Java等語言來編寫頁面程式碼。而且通常情況下HTML程式碼和資料以及對應的邏輯會混在一起,編寫和維護都是非常糟糕的事情。

1.3前端路由階段

前後端分離階段:
隨著Ajax的出現, 有了前後端分離的開發模式。後端只提供API來返回資料, 前端通過Ajax獲取資料, 並且可以通過JavaScript將資料渲染到頁面中。這樣做最大的優點就是前後端責任的清晰, 後端專注於資料上, 前端專注於互動和視覺化上。並且當移動端(iOS/Android)出現後, 後端不需要進行任何處理, 依然使用之前的一套API即可。目前很多的網站依然採用這種模式開發。

單頁面富應用階段:
其實SPA最主要的特點就是在前後端分離的基礎上加了一層前端路由。也就是前端來維護一套路由規則。

前端路由的核心是什麼呢?
改變URL,但是頁面不進行整體的重新整理。如何實現呢?

2.前端路由的規則

2.1URL的hash

URL的hash,URL的hash也就是錨點(#), 本質上是改變window.location的href屬性。我們可以通過直接賦值location.hash來改變href,但是頁面不發生重新整理

image-20200729101456640

2.2HTML5的history模式:pushState

history介面是HTML5新增的, 它有五種模式改變URL而不重新整理頁面。history.pushState()

image-20200729102246390

2.3HTML5的history模式:replaceState

image-20200730090839772

2.4HTML5的history模式:go

image-20200730201615511

3.vue-router基礎

3.1認識vue-router

目前前端流行的三大框架, 都有自己的路由實現:
Angular的ngRouter
React的ReactRouter
Vue的vue-router

當然, 我們的重點是vue-router
vue-router是Vue.js官方的路由外掛,它和vue.js是深度整合的,適合用於構建單頁面應用。
我們可以訪問其官方網站對其進行學習: https://router.vuejs.org/zh/
vue-router是基於路由和元件的路由用於設定訪問路徑,將路徑和元件對映起來。在vue-router的單頁面應用中, 頁面的路徑的改變就是元件的切換。

3.2安裝和使用vue-router

因為我們已經學習了webpack, 後續開發中我們主要是通過工程化的方式進行開發的。所以在後續, 我們直接使用npm來安裝路由即可。
步驟一: 安裝vue-router
npm install vue-router --save

步驟二: 在模組化工程中使用它(因為是一個外掛, 所以可以通過Vue。use()來安裝路由功能)

  • 第一步:匯入路由物件,並且呼叫 Vue。use(VueRouter)
  • 第二步:建立路由例項,並且傳入路由對映配置
  • 第三步:在Vue例項中掛載建立的路由例項

使用vue-router的步驟:

  • 第一步: 建立路由元件
  • 第二步: 配置路由對映: 元件和路徑對映關係
  • 第三步: 使用路由: 通過

3.3Vue案例

1.建立router例項

在用cli3建立vue專案時,我們需要選擇router然後才可以使用,如果建立專案時沒有選擇router,那麼在使用時就需要自己進行安裝

image-20200729103843666

import Vue from 'vue'
import VueRouter from 'vue-router'

//1 注入外掛
Vue.use(VueRouter)

//2 定義路由
const routes =  [
]

//3 建立router例項
const router = new VueRouter({
  routes
})

//4 匯出router例項
export default router

2.掛載到vue例項中

在main.js中引入router

image-20200729103931635

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

Vue.config.productionTip = false

new Vue({
  router, //掛載
  render: h => h(App)
}).$mount('#app')

3.建立路由元件

在views目錄下建立about.vue和home.vue兩個元件

about.vue

<template>
  <div>
      <h2>我是關於標題</h2>
      <p>我是關於內容</p>
  </div>
</template>

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

<style>

</style>

home.vue

<template>
  <div>
      <h2>我是首頁標題</h2>
      <p>我是首頁內容</p>
  </div>
</template>

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

<style>

</style>

4.配置元件和路徑的對映關係

剛才我們已經的index.js中建立了router例項,但是我們並沒有配置路由間的對映關係,現在我們配置對映關係

import Vue from 'vue'
import VueRouter from 'vue-router'

import Home from '../views/home.vue'
import About from '../views/about.vue'

//1 注入外掛
Vue.use(VueRouter)

//2 定義路由
const routes =  [
  //新增對映關係
  {
	//預設首頁
    path: '/',
    redirect: '/home'
  },
  {
    path: '/home',
    component: Home
  },
  {
    path: '/about',
    component: About
  }
]

//3 建立router例項
const router = new VueRouter({
  routes
})

// 4 匯出router例項
export default router

5.使用路由

在App.vue中使用路由

<template>
  <div id="app">
    <router-link to="/home">首頁</router-link>
    <router-link to="/about">關於</router-link>
    <router-view></router-view>
  </div>
</template>

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

<style>

</style>

<router-link>: 該標籤是一個vue-router中已經內建的元件, 它會被渲染成一個<a>標籤。
<router-view>: 該標籤會根據當前的路徑, 動態渲染出不同的元件。網頁的其他內容, 比如頂部的標題/導航, 或者底部的一些版權資訊等會和<router-view>處於同一個等級。在路由切換時, 切換的是<router-view>掛載的元件, 其他內容不會發生改變。

最終效果

image-20200729105638286

4.路由細節處理

4.1路由的預設路徑

我們這裡還有一個不太好的實現:預設情況下, 進入網站的首頁, 我們希望<router-view>渲染首頁的內容。但是我們的實現中, 預設沒有顯示首頁元件, 必須讓使用者點選才可以。如何可以讓路徑預設跳到到首頁, 並且<router-view>渲染首頁元件呢?非常簡單, 我們只需要多配置一個對映就可以了。

//預設首頁
path: '/',
redirect: '/home'
// 配置解析:我們在routes中又配置了一個對映。 
// path配置的是根路徑: /,redirect是重定向, 也就是我們將根路徑重定向到/home的路徑下, 這樣就可以得到我們想要的結果了。

4.2HTML5的History模式

我們前面說過改變路徑的方式有兩種:URL的hash,HTML5的history預設情況下, 路徑的改變使用的URL的hash。如果希望使用HTML5的history模式, 非常簡單, 進行如下配置即可

const router = new VueRouter({
  mode: 'history', //history模式
  routes
})

4.3router-link補充

在前面的<router-link>中, 我們只是使用了一個屬性: to, 用於指定跳轉的路徑。
<router-link>還有一些其他屬性:

  • tag: tag可以指定<router-link>之後渲染成什麼元件, 比如上面的程式碼會被渲染成一個<li>元素, 而不是<a>
  • replace: replace不會留下history記錄, 所以指定replace的情況下, 後退鍵返回不能返回到上一個頁面中
  • active-class: 當<router-link>對應的路由匹配成功時, 會自動給當前元素設定一個router-link-active的class, 設定active-class可以修改預設的名稱。在進行高亮顯示的導航選單或者底部tabbar時, 會使用到該類。但是通常不會修改類的屬性, 會直接使用預設的router-link-active即可。

4.4修改linkActiveClass

該class具體的名稱也可以通過router例項的屬性進行修改

const router = new VueRouter({
  mode: 'history',
  routes,
  linkActiveClass: 'active' //修改類名稱
})

4.5路由的程式碼跳轉

有時候我們需要在路由跳轉的同時執行一些操作,那麼通過<router-link>不是很好實現,這時我們就需要通過JavaScript程式碼進行路由跳轉,將App.vue中程式碼修改如下:

<template>
  <div id="app">
    <!-- <router-link to="/home">首頁</router-link>
    <router-link to="/about">關於</router-link> -->
	
	<!-- 通過程式碼方式進行跳轉 -->
	<button @click="linkToHome">首頁</button>
	<button @click="linktoAbout">關於</button>
    <router-view></router-view>
  </div>
</template>

<script>
  export default {
    name: 'App',
	methods: {
		linkToHome() {
			console.log("跳轉到首頁")
			this.$router.push('/home')
		},
		linktoAbout() {
			console.log("跳轉到關於")
			this.$router.push('/about')
		}
	}
  }
</script>

<style>

</style>

4.6動態路由

在某些情況下,一個頁面的path路徑可能是不確定的,比如我們進入使用者介面時,希望是如下的路徑:/user/aaaa或/user/bbbb,除了有前面的/user之外,後面還跟上了使用者的ID,這種path和Component的匹配關係,我們稱之為動態路由(也是路由傳遞資料的一種方式)。

image-20200729173016913

5.路由巢狀

巢狀路由是一個很常見的功能,比如在home頁面中, 我們希望通過/home/news和/home/message訪問一些內容。一個路徑對映一個元件, 訪問這兩個路徑也會分別渲染兩個元件。

image-20200729174255998

下面我們來做一個路由巢狀的案例

首先定義兩個元件:

message.vue

<template>
	<div>
		<ul>
			<li>message1</li>
			<li>message2</li>
			<li>message3</li>
			<li>message4</li>
			<li>message5</li>
		</ul>
	</div>
	
</template>

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

<style>
</style>

news.vue

<template>
	<div>
		<ul>
			<li>news1</li>
			<li>news2</li>
			<li>news3</li>
			<li>news4</li>
			<li>news5</li>
		</ul>
	</div>
	
</template>

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

<style>
</style>

接著在router/index.js下面加上路由對映

import Vue from 'vue'
import VueRouter from 'vue-router'

import Home from '../views/home.vue'
import About from '../views/about.vue'
import User from '../views/user.vue'

// 加入message.vue
import Message from '../views/message.vue'
import News from '../views/news.vue'

//1 注入外掛
Vue.use(VueRouter)

//2 定義路由
const routes =  [
  //新增對映關係
  {
	//預設首頁
    path: '/',
    redirect: '/home'
  },
  {
    path: '/home',
    component: Home,
	// 路由巢狀
	children: [
		{
			path: '/',
			component: Message
		},
		{
			path: 'message',
			component: Message
		},
		{
			path: 'news',
			component: News
		}
	]
  },
  {
    path: '/about',
    component: About
  },
  {
    path: '/user/:id',
    component: User
  }
]

//3 建立router例項
const router = new VueRouter({
  mode: 'history',
  routes,
  linkActiveClass: 'active' //修改類名稱
})

// 4 匯出router例項
export default router
image-20200729180158119

6.傳遞引數

在進行路由跳轉時,我們有時想要攜帶一些引數,那麼路由的引數該如何來傳遞呢?下面我們一起來學習一下

6.1傳遞引數的方式

傳遞引數主要有兩種型別: params和query
params的型別:
配置路由格式: /router/:id,傳遞的方式: 在path後面跟上對應的值,傳遞後形成的路徑: /router/123, /router/abc

query的型別:
配置路由格式: /router, 也就是普通配置,傳遞的方式: 物件中使用query的key作為傳遞方式,傳遞後形成的路徑: /router?id=123, /router?id=abc

如何使用它們呢? 也有兩種方式: 的方式和JavaScript程式碼方式

傳遞引數方式一:

<!-- 通過router-link進行引數傳遞 -->
<router-link :to="{
	path: '/profile/'+abc,
	query: {name: 'wugongzi', age: 18}
}"></router-link>

傳遞引數方式二: JavaScript程式碼

<!-- 通過程式碼進行引數傳遞 -->
<button @click="linktoProfile">檔案</button>

linktoProfile() {
    this.$router.push({
        path: '/profile/' + abc,
        query: {
            name: 'wugongzi',
            age: 18
        }
    })
}

6.2獲取引數

獲取引數通過$route物件獲取的。在使用了 vue-router 的應用中,路由物件會被注入每個元件中,賦值為 this.$route ,並且當路由切換時,路由物件會被更新。通過$route獲取傳遞的資訊如下:

image-20200731095553969

$route和$router是有區別的

  • $router為VueRouter例項,想要導航到不同URL,則使用$router.push方法

  • $route為當前router跳轉物件裡面可以獲取name、path、query、params等

image-20200731095648469

相關文章