Vue2.0路由vue-router
# vue-router的基本使用
1. 什麼是vue-router
vue-router 是 vue.js 官方給出的路由解決方案。它只能結合 vue 專案進行使用,能夠輕鬆的管理 SPA(單頁面應用程式) 專案 中元件的切換。
2. vue-router安裝和配置步驟
① 安裝 vue-router 包
② 建立路由模組
③ 匯入並掛載路由模組
④ 宣告路由連結和佔位符
2.1 在Vue2專案中安裝 vue-router
npm i vue-router@指定版本 -S
2.2 建立路由模組
在 src 原始碼目錄下,新建 router/index.js 路由模組,並初始化如下的程式碼:
檢視程式碼
// src/router/index.js 就是當前專案的路由模組
// 1. 匯入 Vue 和VueRouter 的包
import Vue from 'vue'
import VueRouter from 'vue-router'
// 2. 把 VueRouter 安裝為 Vue 專案的外掛
// Vue.use() 函式的作用,就是來安裝外掛的
Vue.use(VueRouter)
// 3. 建立路由的例項物件
const router = new VueRouter( )
// 4. 向外共享路由例項物件
export default router
2.3 匯入並掛載路由模組
在 src/main.js 入口檔案中,匯入並掛載router/index.js路由模組,如下:
檢視程式碼
import Vue from 'vue' import App from './App.vue' // 1. 匯入路由模組,目的:拿到路由的例項物件 // 在模組化匯入的時候,如果給定的是資料夾,則預設匯入這個資料夾下的 index.js import router from '@/router' Vue.config.productionTip = false new Vue({ render: h => h(App), // 2. 把路由例項物件進行掛載 // router: 路由的例項物件 // router:router ES6簡寫 router router }).$mount('#app')
2.4 宣告路由連結和佔位符
在 src/App.vue 元件中,使用 vue-router 提供的 <router-link> 和 <router-view> 宣告路由連結和佔位符:
檢視程式碼
<template>
<div class="app-container">
<!-- 當安裝和配置了 vue-router 後,就可以使用 router-link 來替代普通的 a 連結了 -->
<!-- <a href="#/home">首頁</a> -->
<router-link to="/home">首頁</router-link>
<router-link to="/movie">電影</router-link>
<router-link to="/about">關於</router-link>
<!-- 只要在專案中安裝和配置了 vue-router,就可以使用 router-view 這個元件了 -->
<!-- 它的作用很單純:佔位符 -->
<router-view></router-view>
</div>
</template>
3. 宣告路由的匹配規則
在 src/router/index.js 路由模組中,通過 routes 陣列宣告路由的匹配規則。示例程式碼如下:
檢視程式碼
// 1. 匯入需要的元件
import Home from '@/components/Home.vue'
import Movie from '@/components/Movie.vue'
import About from '@/components/About.vue'
// 2. 在路由的例項物件中宣告路由規則
const router = new VueRouter({
// routes 是一個數組,作用:定義 “hash 地址” 與 “元件” 之間的對應關係
routes: [
// 路由規則
{ path: '/home', component: Home },
{ path: '/movie', component: Movie },
{ path: '/about', component: About }
]
})
# vue-router的常見使用
1. 路由的重定向
路由重定向指的是:使用者在訪問地址 A 的時候,強制使用者跳轉到地址 B ,從而展示特定的元件頁面。 通過路由規則的 redirect 屬性,指定一個新的路由地址,可以很方便地設定路由的重定向:
檢視程式碼
// src/router/index.js檔案
const router = new VueRouter({
routes: [
// 重定向的路由規則,當用戶訪問 / 的時候,自動程式設計訪問 /home
{ path: '/', redirect: '/home' },
{ path: '/home', component: Home },
{ path: '/movie, component: Movie },
{ path: '/about',component: About, }
]
})
2. 巢狀路由
通過路由實現元件的巢狀展示,叫做巢狀路由。
2.1 宣告子路由連結和子路由佔位符
比如,在 About.vue 元件中,宣告 tab1 和 tab2 的子路由連結以及子路由佔位符。如下:
檢視程式碼
<template>
<div class="about-container">
<!-- 在關於頁面中,宣告兩個子級路由連結 -->
<router-link to="/about">tab1</router-link> //使用預設路由
<router-link to="/about/tab2">tab2</router-link>
<!-- 在關於頁面中,宣告子級路由佔位符 -->
<router-view></router-view>
</div>
</template>
2.2 通過 children 屬性宣告子路由規則
在 src/router/index.js 路由模組中,匯入需要的元件,並使用 children 屬性宣告子路由規則:
檢視程式碼
// src/router/index.js檔案
const router = new VueRouter({
routes: [
path: '/about',
component: About,
// 子路由規則
children: [
// 預設子路由:如果 children 陣列中,某個路由規則的 path 值為空字串,則這條路由規則,叫做“預設子路由”
{ path: '', component: Tab1 },
{ path: 'tab2', component: Tab2 }
]
]
})
3. 動態路由匹配
3.1 動態路由概念
動態路由指的是:把 Hash 地址中可變的部分定義為引數項,從而提高路由規則的複用性。 在 vue-router 中使用英文的冒號( : )來定義路由的引數項。示例程式碼如下:
檢視程式碼
// src/router/index.js檔案
const router = new VueRouter({
routes: [
{ path: '/home', component: Home },
// 需求:在 Movie 元件中,希望根據 id 的值,展示對應電影的詳情資訊
// 開啟 props: true 選項,可以為路由規則開啟 props 傳參,從而方便的拿到動態引數的值
{ path: '/movie/:mid', component: Movie, props: true },
]
})
// src/components/Movie.vue檔案
<template>
<div class="movie-container">
<!-- 方式1:通過 this.$route.params.mid 獲得路由動態引數 是路由的“引數物件” -->
<!-- this.$route 是路由的“引數物件” -->
<h3>Movie 元件 --- {{ $route.params.mid }} --- {{ mid }}</h3>
</div>
</template>
<script>
export default {
name: 'Movie',
// 方式2:路由匹配規則中開啟了props: true 選項通過接收 props 資料
props: ['mid']
}
</script>
4. 宣告式導航&程式設計式導航
瀏覽器中,點選連結實現導航的方式,叫做宣告式導航。例如:
- 普通網頁中點選 <a> 連結、vue 專案中點選 <router-link> 都屬於宣告式導航
在瀏覽器中,呼叫 API 方法實現導航的方式,叫做程式設計式導航。例如:
- 普通網頁中呼叫 location.href 跳轉到新頁面的方式,屬於程式設計式導航
3.1 vue-router 中的程式設計式導航 API
vue-router 提供了許多程式設計式導航的 API,其中最常用的導航 API 分別是:
① this.$router.push('hash 地址')
- 跳轉到指定 hash 地址,有歷史記錄
② this.$router.replace('hash 地址')
- 跳轉到指定的hash地址,沒有歷史記錄
③ this.$router.go(數值 n)
- 實現導航歷史前進、後退
檢視程式碼
// src/components/Movie.vue檔案
<template>
<div class="home-container">
<!-- 在行內使用程式設計式導航跳轉的時候,this 必須要省略,否則會報錯! -->
<button @click="$router.push('/movie/1')">通過 push 跳轉到“1”頁面</button>
<button @click="$router.replace('/movie/2')">通過 replace 跳轉到“2”頁面</button>
<button @click="$router.go(-1)>通過go 後退
</div>
</template>
// $router.go 有簡化用法
$router.back() 在歷史記錄中,後退到上一個頁面
$router.forward() 在歷史記錄中,前進到下一個頁面
<template>
<div class="home-container">
<!-- 在行內使用程式設計式導航跳轉的時候,this 必須要省略,否則會報錯! -->
<button @click="$router.back()> 後退 </button>
<button @click="$router.forward()> 前進 </button>
</div>
</template>
5. 導航守衛
導航守衛可以控制路由的訪問許可權。比如用於登入後臺,未登入的需要跳轉到登入頁面。
5.1 全域性前置守衛
可以在 src/router/index.js 中設定全域性前置守衛。每次發生路由的導航跳轉時,都會觸發全域性前置守衛。因此,在全域性前置守衛中,程式設計師可以對每個路由進行訪問許可權的控制。
全域性前置守衛的回撥函式中接收3個形參:
檢視程式碼
router.beforeEach(function(to, from, next) {
// to 表示將要訪問的路由的資訊物件
// from 表示將要離開的路由的資訊物件
// next() 函式表示放行的意思
}
後臺登入案例中:
當前使用者擁有後臺主頁的訪問許可權,直接放行:next()
當前使用者沒有後臺主頁的訪問許可權,強制其跳轉到登入頁面:next('/login')
當前使用者沒有後臺主頁的訪問許可權,不允許跳轉到後臺主頁:next(false)
檢視程式碼
// 為 router 例項物件,宣告全域性前置導航守衛
// 只要發生了路由的跳轉,必然會觸發 beforeEach 指定的 function 回撥函式
router.beforeEach(function(to, from, next) {
// to 表示將要訪問的路由的資訊物件
// from 表示將要離開的路由的資訊物件
// next() 函式表示放行的意思
// 分析:
// 1. 要拿到使用者將要訪問的 hash 地址
// 2. 判斷 hash 地址是否等於 /main。
// 2.1 如果等於 /main,證明需要登入之後,才能訪問成功
// 2.2 如果不等於 /main,則不需要登入,直接放行 next()
// 3. 如果訪問的地址是 /main。則需要讀取 localStorage 中的 token 值
// 3.1 如果有 token,則放行
// 3.2 如果沒有 token,則強制跳轉到 /login 登入頁
if (to.path === '/main') {
// 要訪問後臺主頁,需要判斷是否有 token
const token = localStorage.getItem('token')
if (token) {
next()
} else {
// 沒有登入,強制跳轉到登入頁
next('/login')
}
} else {
next()
}
})
# src/router/index.js示例
檢視程式碼
// src/router/index.js 就是當前專案的路由模組
import Vue from 'vue'
import VueRouter from 'vue-router'
// 匯入需要的元件
import Home from '@/components/Home.vue'
import Movie from '@/components/Movie.vue'
import About from '@/components/About.vue'
import Tab1 from '@/components/tabs/Tab1.vue'
import Tab2 from '@/components/tabs/Tab2.vue'
import Login from '@/components/Login.vue'
import Main from '@/components/Main.vue'
// 把 VueRouter 安裝為 Vue 專案的外掛
// Vue.use() 函式的作用,就是來安裝外掛的
Vue.use(VueRouter)
// 建立路由的例項物件
const router = new VueRouter({
// routes 是一個數組,作用:定義 “hash 地址” 與 “元件” 之間的對應關係
routes: [
// 重定向的路由規則
{ path: '/', redirect: '/home' },
// 路由規則
{ path: '/home', component: Home },
// 需求:在 Movie 元件中,希望根據 id 的值,展示對應電影的詳情資訊
// 可以為路由規則開啟 props 傳參,從而方便的拿到動態引數的值
{ path: '/movie/:mid', component: Movie, props: true },
{
path: '/about',
component: About,
// redirect: '/about/tab1',
children: [
// 子路由規則
// 預設子路由:如果 children 陣列中,某個路由規則的 path 值為空字串,則這條路由規則,叫做“預設子路由”
{ path: '', component: Tab1 },
{ path: 'tab2', component: Tab2 }
]
},
{ path: '/login', component: Login },
{ path: '/main', component: Main }
]
})
// 為 router 例項物件,宣告全域性前置導航守衛
// 只要發生了路由的跳轉,必然會觸發 beforeEach 指定的 function 回撥函式
router.beforeEach(function(to, from, next) {
// to 表示將要訪問的路由的資訊物件
// from 表示將要離開的路由的資訊物件
// next() 函式表示放行的意思
// 分析:
// 1. 要拿到使用者將要訪問的 hash 地址
// 2. 判斷 hash 地址是否等於 /main。
// 2.1 如果等於 /main,證明需要登入之後,才能訪問成功
// 2.2 如果不等於 /main,則不需要登入,直接放行 next()
// 3. 如果訪問的地址是 /main。則需要讀取 localStorage 中的 token 值
// 3.1 如果有 token,則放行
// 3.2 如果沒有 token,則強制跳轉到 /login 登入頁
if (to.path === '/main') {
// 要訪問後臺主頁,需要判斷是否有 token
const token = localStorage.getItem('token')
if (token) {
next()
} else {
// 沒有登入,強制跳轉到登入頁
next('/login')
}
} else {
next()
}
})
export default router