一、前端路由的概念與原理
1、 什么是路由
路由(英文:router)就是對應關系
2、SPA 與前端路由
- SPA 指的是一個 web 網站只有唯一的一個 HTML 頁面,所有組件的展示與切換都在這唯一的一個頁面內完成。
- 此時,不同組件之間的切換需要通過前端路由來實現。
- 結論:在 SPA 項目中,不同功能之間的切換,要依賴于前端路由來完成!
3、什么是前端路由
通俗易懂的概念:Hash 地址與組件之間的對應關系
4、前端路由的工作方式
① 用戶點擊了頁面上的路由鏈接
② 導致了 URL 地址欄中的 Hash 值發(fā)生了變化
③ 前端路由監(jiān)聽了到 Hash 地址的變化
④ 前端路由把當前 Hash 地址對應的組件渲染都瀏覽器中
5、實現簡易的前端路由
步驟1:通過 <component>
標簽,結合 comName
動態(tài)渲染組件。示例代碼如下:
<component :is="comName"></component>
export default {
name: 'App',
data() {
return {
// 在動態(tài)組件的位置,要展示的組件的名字,值必須是字符串
comName: 'Home'
}
}
}
步驟2:在 App.vue 組件中,為 <a>
鏈接添加對應的 hash
值
<a href="#/home">首頁</a>
<a href="#/movie">電影</a>
<a href="#/about">關于</a>
步驟3:在 created
生命周期函數中,監(jiān)聽瀏覽器地址欄中 hash
地址的變化,動態(tài)切換要展示的組件的名稱
created() {
// 只要當前的 App 組件一被創(chuàng)建,就立即監(jiān)聽 window 對象的 onhashchange 事件
window.onhashchange = () => {
console.log('監(jiān)聽到了 hash 地址的變化', location.hash)
switch (location.hash) {
case '#/home':
this.comName = 'Home'
break
case '#/movie':
this.comName = 'Movie'
break
case '#/about':
this.comName = 'About'
break
}
}
},
二、vue-router 的基本用法
1、 什么是 vue-router
vue-router
是 vue.js 官方給出的路由解決方案。它只能結合 vue 項目進行使用,能夠輕松的管理 SPA 項目中組件的切換。
vue-router
的官方文檔地址:https://router.vuejs.org/zh/
2、 vue-router 安裝和配置的步驟
① 安裝 vue-router 包
② 創(chuàng)建路由模塊
③ 導入并掛載路由模塊
④ 聲明路由鏈接和占位符
(1)在項目中安裝 vue-router
在 vue2 的項目中,安裝 vue-router
的命令如下:
npm i vue-router@3.5.2 -s
(2) 創(chuàng)建路由模塊
在 src 源代碼目錄下,新建 router/index.js
路由模塊,并初始化如下的代碼:
import Vue from 'vue'
import VueRouter from 'vue-router'
// 把 VueRouter 安裝為 Vue 項目的插件
// Vue.use() 函數的作用,就是來安裝插件的
Vue.use(VueRouter)
// 創(chuàng)建路由的實例對象
const router = new VueRouter()
export default router
(3)導入并掛載路由模塊
在 src/main.js
入口文件中,導入并掛載路由模塊。示例代碼如下:
// 導入路由模塊,目的:拿到路由的實例對象
// 在進行模塊化導入的時候,如果給定的是文件夾,則默認導入這個文件夾下,名字叫做 index.js 的文件
import router from '@/router'
new Vue({
render: h => h(App),
// 在 Vue 項目中,要想把路由用起來,必須把路由實例對象,通過下面的方式進行掛載
// router: 路由的實例對象
router
}).$mount('#app')
(4)聲明路由鏈接和占位符
在 src/App.vue
組件中,使用 vue-router 提供的 <router-link>
和 <router-view>
聲明路由鏈接和占位符
<template>
<div class="app-container">
<h1>App 根組件</h1>
<router-link to="/home">首頁</router-link>
<router-link to="/movie">電影</router-link>
<router-link to="/about">關于</router-link>
<hr />
<component :is="comName"></component>
</div>
</template>
3、 聲明路由的匹配規(guī)則
在 src/router/index.js
路由模塊中,通過 routes
數組聲明路由的匹配規(guī)則。示例代碼如下:
// 導入需要的組件
import Home from '@/components/Home.vue'
import Movie from '@/components/Movie.vue'
import About from '@/components/About.vue'
// 創(chuàng)建路由的實例對象
const router = new VueRouter({
// routes 是一個數組,作用:定義 “hash 地址” 與 “組件” 之間的對應關系
routes: [
{ path: '/home', component: Home },
{ path: '/movie', component: Movie },
{ path: '/about',component: About },
]
})
三、vue-router 的常見用法
1、路由重定向
- 路由重定向指的是:用戶在訪問地址 A 的時候,強制用戶跳轉到地址 C ,從而展示特定的組件頁面。
- 通過路由規(guī)則的
redirect
屬性,指定一個新的路由地址,可以很方便地設置路由的重定向
const router = new VueRouter({
routes: [
// 重定向的路由規(guī)則
{ path: '/', redirect: '/home' },
{ path: '/home', component: Home },
{ path: '/movie', component: Movie },
{ path: '/about',component: About },
]
})
2、嵌套路由
通過路由實現組件的嵌套展示,叫做嵌套路由。
(1)聲明子路由鏈接和子路由占位符
在 About.vue 組件中,聲明 tab1 和 tab2 的子路由鏈接以及子路由占位符。示例代碼如下 :
<template>
<div class="about-container">
<h3>About 組件</h3>
<!-- 子級路由鏈接 -->
<router-link to="/about/tab1">tab1</router-link>
<router-link to="/about/tab2">tab2</router-link>
<hr />
<!-- 子級路由占位符 -->
<router-view></router-view>
</div>
</template>
(2)通過 children 屬性聲明子路由規(guī)則
在 src/router/index.js 路由模塊中,導入需要的組件,并使用 children 屬性聲明子路由規(guī)則:
import Tab1 from '@/components/tabs/Tab1.vue'
import Tab2 from '@/components/tabs/Tab2.vue'
const router = new VueRouter({
routes: [
{
path: '/about',
component: About,
children: [
{ path: 'tab1', component: Tab1 },
{ path: 'tab2', component: Tab2 }
]
}
]
})
(3)默認子路由
第一種:
<!-- // 子級路由鏈接 -->
<router-link to="/about/tab1">tab1</router-link>
<router-link to="/about/tab2">tab2</router-link>
{
path: '/about',
component: About,
redirect: '/about/tab1',
children: [
// 子路由規(guī)則
// 默認子路由:如果 children 數組中,某個路由規(guī)則的 path 值為空字符串,則這條路由規(guī)則,叫做“默認子路由”
{ path: 'tab1', component: Tab1 },
{ path: 'tab2', component: Tab2 }
]
},
第二種:
<!-- // 子級路由鏈接 -->
<router-link to="/about">tab1</router-link>
<router-link to="/about/tab2">tab2</router-link>
{
path: '/about',
component: About,
children: [
// 子路由規(guī)則
// 默認子路由:如果 children 數組中,某個路由規(guī)則的 path 值為空字符串,則這條路由規(guī)則,叫做“默認子路由”
{ path: '', component: Tab1 },
{ path: 'tab2', component: Tab2 }
]
},
3、動態(tài)路由匹配
(1)動態(tài)路由的概念
- 動態(tài)路由指的是:把 Hash 地址中可變的部分定義為參數項,從而提高路由規(guī)則的復用性。
- 在 vue-router 中使用英文的冒號
(:)
來定義路由的參數項。示例代碼如下:
{ path: '/movie/:mid', component: Movie, props: true },
// 將以下3個合并成一個,提高了復用性
{ path: '/movie/1', component: Movie, props: true },
{ path: '/movie/2', component: Movie, props: true },
{ path: '/movie/3', component: Movie, props: true },
(2)$route.params 參數對象
在動態(tài)路由渲染出來的組件中,可以使用 this.$route.params
對象訪問到動態(tài)匹配的參數值。
<template>
<div class="movie-container">
//this.可以省略
<h3>Movie 組件 --- {{ this.$route.params.mid }} </h3>
</div>
</template>
<script>
export default {
name: 'Movie'
}
</script>
(3)使用 props 接收路由參數
為了簡化路由參數的獲取形式,vue-router 允許在路由規(guī)則中開啟 props 傳參。示例代碼如下:
// 可以為路由規(guī)則開啟 props 傳參,從而方便的拿到動態(tài)參數的值
{ path: '/movie/:mid', component: Movie, props: true },
<template>
<div class="movie-container">
<h3>Movie 組件 --- {{ $route.params.mid }} --- {{ mid }}</h3>
</div>
</template>
<script>
export default {
// 接收 props 數據
props: ['mid']
}
</script>
(4)query參數和fullPath
- hash 地址中,
/
后面的參數項,叫做“路徑參數”,要使用this.$route.params
來訪問 - 在 hash 地址中,
?
后面的參數項,叫做“查詢參數” ,要使用this.$route.query
來訪問查詢參數 - 在
this.$route
中,path
只是路徑部分;fullPath
是完整的地址 - 例如:
/movie/2?name=zs&age=20
是fullPath
的值;/movie/2
是path
的值
<router-link to="/movie/2?name=zs&age=20">雷神</router-link>
4、聲明式導航 & 編程式導航
在瀏覽器中,點擊鏈接實現導航的方式,叫做聲明式導航。例如:
? 普通網頁中點擊 <a>
鏈接、vue 項目中點擊 <router-link>
都屬于聲明式導航
在瀏覽器中,調用 API 方法實現導航的方式,叫做編程式導航。例如:
? 普通網頁中調用 location.href
跳轉到新頁面的方式,屬于編程式導航
(1) vue-router 中的編程式導航 API
vue-router 提供了許多編程式導航的 API,其中最常用的導航 API 分別是:
① this.$router.push('hash 地址')
? 跳轉到指定 hash 地址,并增加一條歷史記錄
② this.$router.replace('hash 地址')
? 跳轉到指定的 hash 地址,并替換掉當前的歷史記錄
③ this.$router.go(數值 n)
? 實現導航歷史前進、后退
(2)$router.push
調用 this.$router.push()
方法,可以跳轉到指定的 hash 地址,從而展示對應的組件頁面。示例代碼如下:
<template>
<div class="home-container">
<h3>Home 組件</h3>
<hr />
<button @click="gotoLk">通過 push 跳轉到“洛基”頁面</button>
</div>
</template>
<script>
export default {
name: 'Home',
methods: {
gotoLk() {
// 通過編程式導航 API,導航跳轉到指定的頁面
this.$router.push('/movie/1')
}
}
}
</script>
(3)$router.replace
調用 this.$router.replace()
方法,可以跳轉到指定的 hash 地址,從而展示對應的組件頁面。
push 和 replace 的區(qū)別:
? push
會增加一條歷史記錄
? replace
不會增加歷史記錄,而是替換掉當前的歷史記錄
<template>
<div class="home-container">
<h3>Home 組件</h3>
<hr />
<button @click="gotoLk2">通過 replace 跳轉到“洛基”頁面</button>
</div>
</template>
<script>
export default {
name: 'Home',
methods: {
gotoLk2() {
this.$router.replace('/movie/1')
}
}
}
</script>
(4)$router.go
調用 this.$router.go()
方法,可以在瀏覽歷史中前進和后退。示例代碼如下:
<template>
<div class="movie-container">
<button @click="goback">后退</button>
</div>
</template>
<script>
export default {
name: 'Movie',
methods: {
goback() {
// go(-1) 表示后退一層
// 如果后退的層數超過上限,則原地不動
this.$router.go(-1)
}
}
}
</script>
(5)$router.go 的簡化用法
在實際開發(fā)中,一般只會前進和后退一層頁面。因此 vue-router 提供了如下兩個便捷方法:
① $router.back()
? 在歷史記錄中,后退到上一個頁面
② $router.forward()
? 在歷史記錄中,前進到下一個頁面
注意:在行內使用編程式導航跳轉的時候,this 必須要省略,否則會報錯
<template>
<div class="movie-container">
<!-- 在行內使用編程式導航跳轉的時候,this 必須要省略,否則會報錯! -->
<button @click="$router.back()">back 后退</button>
<button @click="$router.forward()">forward 前進</button>
</div>
</template>
5、導航守衛(wèi)
導航守衛(wèi)可以控制路由的訪問權限。示意圖如下:
(1)全局前置守衛(wèi)
每次發(fā)生路由的導航跳轉時,都會觸發(fā)全局前置守衛(wèi)beforeEach()
。因此,在全局前置守衛(wèi)中,程序員可以對每個路由進行訪問權限的控制
const router = new VueRouter({···})
// 為 router 實例對象,聲明全局前置導航守衛(wèi)
// 只要發(fā)生了路由的跳轉,必然會觸發(fā) beforeEach 指定的 function 回調函數
router.beforeEach(function(to, from, next) {})
(2)守衛(wèi)方法的 3 個形參
全局前置守衛(wèi)的回調函數中接收 3 個形參to, from, next
,格式為:文章來源:http://www.zghlxwxcb.cn/news/detail-734087.html
router.beforeEach(function(to, from, next) {
// to 表示將要訪問的路由的信息對象
// from 表示將要離開的路由的信息對象
// next() 函數表示放行的意思
})
-
to
表示將要訪問的路由的信息對象 -
from
表示將要離開的路由的信息對象 -
next
() 函數表示放行的意思
(3)next 函數的 3 種調用方式
參考示意圖,分析 next 函數的 3 種調用方式最終導致的結果:文章來源地址http://www.zghlxwxcb.cn/news/detail-734087.html
- 當前用戶擁有后臺主頁的訪問權限,直接放行:
next()
- 當前用戶沒有后臺主頁的訪問權限,強制其跳轉到登錄頁面:
next('/login')
- 當前用戶沒有后臺主頁的訪問權限,不允許跳轉到后臺主頁(保留在當前所處的頁面):
next(false)
(4)控制后臺主頁的訪問權限
router.beforeEach(function(to, from, next) {
if (to.path === '/main') {
// 要訪問后臺主頁,需要判斷是否有 token
const token = localStorage.getItem('token')
if (token) {
next()
} else {
// 沒有登錄,強制跳轉到登錄頁
next('/login')
}
} else {
next()
}
})
到了這里,關于路由vue-router的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!