Vue.js-vuerouter詳解
1.1 什麼是路由
路由(routing)就是通過互聯的網路把資訊從源地址傳輸到目的地址的活動。路由中有一個非常重要的概念叫路由表,路由表本質上就是一個對映表, 決定了資料包的指向。
後端路由渲染(JSP)
早期的網站開發整個HTML頁面是由伺服器來渲染的,伺服器直接生產渲染好對應的HTML頁面, 返回給客戶端進行展示。後端處理URL和頁面之間的對映關係!!
具體流程
-
一個頁面有自己對應的網址, 也就是URL。
-
URL會發送到伺服器, 伺服器會通過正則對該URL進行匹配, 並且最後交給一個控制器進行處理。
-
控制器進行各種處理, 最終生成HTML或者資料, 返回給前端(Java程式碼作用是從資料庫中讀取資料,並將它動態的放在頁面中)。
後端渲染優點
當頁面中需要請求不同的路徑內容時, 交給伺服器來進行處理, 伺服器渲染好整個頁面, 並且將頁面返回給客戶頓。
這種情況下渲染好的頁面, 不需要單獨載入任何的js和css, 可以直接交給瀏覽器展示, 這樣也有利於SEO的優化。
後端渲染缺點
- 是整個頁面的模組由後端人員來編寫和維護的。
- 另一種情況是前端開發人員如果要開發頁面, 需要通過PHP和Java等語言來編寫頁面程式碼。
- 而且通常情況下HTML程式碼和資料以及對應的邏輯會混在一起, 編寫和維護都是非常糟糕的事情。
前後端分離階段
前後端分離優點
- 隨著Ajax的出現, 有了前後端分離的開發模式,後端只提供API來返回資料, 前端通過Ajax獲取資料, 並且可以通過JavaScript將資料渲染到頁面中。
- 這樣做最大的優點就是前後端責任的清晰, 後端專注於資料上, 前端專注於互動和視覺化上。
- 並且當移動端(iOS/Android)出現後, 後端不需要進行任何處理, 依然使用之前的一套API即可,目前很多的網站依然採用這種模式開發。
SPA頁面階段
SPA頁面是單頁富應用,整個網頁只有一個html頁面!!!其實SPA最主要的特點就是在前後端分離的基礎上加了一層前端路由。
1.2 認識vue-router
建立專案
vue init webpack 05-vueroutertest
vue-router是Vue.js官方的路由外掛,它和vue.js是深度整合的,適合用於構建單頁面應用。
vue-router是基於路由和元件的
路由用於設定訪問路徑, 將路徑和元件對映起來,在vue-router的單頁面應用中, 頁面的路徑的改變就是元件的切換。
1.2.1 安裝vue-router
步驟一: 安裝vue-router
cnpm install vue-router --save
步驟二: 在模組化工程中使用它(因為是一個外掛, 所以可以通過Vue.use()來安裝路由功能)
- 第一步:匯入路由物件,並且呼叫 Vue.use(VueRouter)。
- 第二步:建立路由例項,並且傳入路由對映配置。
-
第三步:在Vue例項中掛載建立的路由例項
1.2.2 使用vue-router的步驟
第一步: 建立路由元件。
第二步: 配置路由對映: 元件和路徑對映關係。
第三步: 使用路由: 通過<router-link>和<router-view>
。
<router-link>
: 該標籤是一個vue-router中已經內建的元件, 它會被渲染成一個<a>
標籤。<router-view>
: 該標籤會根據當前的路徑, 動態渲染出不同的元件。- 網頁的其他內容, 比如頂部的標題/導航, 或者底部的一些版權資訊等會和
<router-view>
處於同一個等級。 - 在路由切換時, 切換的是
<router-view>
掛載的元件, 其他內容不會發生改變。
執行結果
路由的預設路徑
讓路徑預設跳到到首頁, 並且<router-view>
渲染首頁元件。
index.js
配置解析:
- 在routes中又配置了一個對映,path配置的是根路徑: /
- redirect是重定向, 也就是我們將根路徑重定向到/home的路徑下。
HTML5的History模式
- 改變路徑的方式有兩種: URL的hash,HTML5的history。
- 預設情況下, 路徑的改變使用的URL的hash。
如果希望使用HTML5的history模式, 非常簡單, 進行如下配置即可。
router-link其他屬性
-
tag可以指定
<router-link>
之後渲染成什麼元件。 -
replace不會留下history記錄, 所以指定replace的情況下, 後退鍵返回不能返回到上一個頁面中。
-
當
<router-link>
對應的路由匹配成功時, 會自動給當前元素設定一個router-link-active的class,設定active-class可以修改預設的名稱。但是通常不會修改類的屬性, 會直接使用預設的router-link-active即可。
修改linkActiveClass
class具體的名稱也可以通過router例項的屬性進行修改。exact-active-class類似於active-class, 只是在精準匹配下才會出現的class。
1.2.3 路由程式碼跳轉
有時候, 頁面的跳轉可能需要執行對應的JavaScript程式碼, 這個時候, 就可以使用第二種跳轉方式了。
1.3 路由的懶載入
1.3.1 動態路由
在某些情況下,一個頁面的path路徑可能是不確定的,當進入使用者介面時,希望是如下的路徑。
/user/userid或/user/username,這種path和Component的匹配關係,稱之為動態路由。
程式碼示例
User.vue
<template>
<div>
<h3>使用者介面</h3>
<p>學習Vue.js!!!</p>
<h3>{{userId}}</h3>
<!--直接拿-->
<!-- <h2>{{$route.params.userid}}</h2> -->
</div>
</template>
<script>
export default {
name: "User",
computed:{
userId(){
// 拿到的是哪個路由處於活躍狀態,就是拿到哪個路由!!
return this.$route.params.userid
}
}
}
</script>
<style scoped>
</style>
index.js
// 配置路由相關的資訊
import Vue from 'vue'
// 匯入元件
import User from "../components/User";
import VueRouter from 'vue-router';
// 1.通過Vue.use(外掛),安裝外掛
Vue.use(VueRouter)
// 2.定義路由
const routes = [
{
path:'/user/:userid',
component: User
}
]
// 3.建立router例項
const router = new VueRouter({
// 配置路由和元件之間的應用關係
routes,
mode:'history',
linkActiveClass: 'active'
})
// 4.匯出router例項
export default router
APP.vue
<template>
<div id="app">
<h2>中國大學mooc</h2>
<router-link :to="'/user/'+ userId" tag="button" replace>使用者</router-link>
<router-view></router-view>
<h3>沒有圍牆的大學!!</h3>
</div>
</template>
<script>
export default {
name: 'App',
data() {
return {
userId: 'guardwhy'
}
}
}
</script>
<style>
.active{
color: red;
}
</style>
執行結果
1.3.2 路由的懶載入
當打包構建應用時,Javascript 包會變得非常大,影響頁面載入。
如果能把不同路由對應的元件分割成不同的程式碼塊,然後當路由被訪問的時候才載入對應元件,這樣就更加高效了。
路由懶載入做了什麼?
路由懶載入的主要作用就是將路由對應的元件打包成一個個的js程式碼塊。
只有在這個路由被訪問到的時候, 才載入對應的元件。
懶載入的方式
方式一: 結合Vue的非同步元件和Webpack的程式碼分析。
const Home = resolve => { require.ensure(['../components/Home.vue'], () => { resolve(require('../components/Home.vue')) })};
方式二: AMD寫法
const About = resolve => require(['../components/About.vue'], resolve);
方式三: 在ES6中, 我們可以有更加簡單的寫法來組織Vue非同步元件和Webpack的程式碼分割。
const Home = () => import('../components/Home.vue')
路由懶載入的效果
1.4 巢狀路由
巢狀路由是一個很常見的功能。比如在home頁面中, 希望通過/home/news和/home/message訪問一些內容,一個路徑對映一個元件, 訪問這兩個路徑也會分別渲染兩個元件。
路徑和元件的關係如下
實現巢狀路由有兩個步驟
建立對應的子元件, 並且在路由對映中配置對應的子路由。
index.js
在元件內部使用<router-view>
標籤。
執行結果
14.5 傳遞引數的方式
傳遞引數主要有兩種型別: params和query。
params的型別
- 配置路由格式: /router/:id
- 傳遞的方式: 在path後面跟上對應的值
- 傳遞後形成的路徑: /router/123, /router/abc。
query的型別
- 配置路由格式: /router, 也就是普通配置。
- 傳遞的方式: 物件中使用query的key作為傳遞方式。
- 傳遞後形成的路徑: /router?id=123, /router?id=abc。
傳遞引數方式一:
Profile.vue
<template>
<div>
<p>使用者基本檔案</p>
</div>
</template>
<script>
export default {
name:"Profile"
}
</script>
<style scoped>
</style>
index.js
// 配置路由相關的資訊
import Vue from 'vue'
// 匯入元件
import VueRouter from 'vue-router';
// 路由懶載入
const Profile = () => import('../components/Profile')
// 1.通過Vue.use(外掛),安裝外掛
Vue.use(VueRouter)
// 2.定義路由
const routes = [
{
path:'/profile',
component:Profile
}
]
// 3.建立router例項
const router = new VueRouter({
// 配置路由和元件之間的應用關係
routes,
mode:'history',
linkActiveClass: 'active'
})
// 4.匯出router例項
export default router
App.vue
傳遞引數方式二: JavaScript程式碼
App.vue
<template>
<div id="app">
<h2>中國大學mooc</h2>
<button @click="userClick">使用者</button>
<button @click="profileClick">檔案</button>
<router-view></router-view>
<h3>沒有圍牆的大學!!</h3>
</div>
</template>
<script>
export default {
name: 'App',
data() {
return {
userId: 'guardwhy'
}
},
methods: {
userClick(){
this.$router.push('/user/'+ this.userId)
},
profileClick(){
this.$router.push({
path: '/profile',
query:{
name: 'guardwhy',
age : 28,
height: 1.72
}
})
}
},
}
</script>
<style>
.active{
color: red;
}
</style>
獲取引數
獲取引數通過$route物件獲取的,在使用了 vue-router 的應用中,路由物件會被注入每個元件中,賦值為 this.$route ,並且當路由切換時,路由物件會被更新。
1.6 導航守衛
1.6.1 為什麼使用導航守衛?
普通的修改方式
- 能比較容易想到的修改標題的位置是每一個路由對應的元件.vue檔案中。
- 通過mounted宣告周期函式, 執行對應的程式碼進行修改即可。
- 但是當頁面比較多時, 這種方式不容易維護(因為需要在多個頁面執行類似的程式碼)。
什麼是導航守衛?
vue-router提供的導航守衛主要用來監聽監聽路由的進入和離開的。
vue-router提供了beforeEach和afterEach的鉤子函式, 它們會在路由即將改變前和改變後觸發.
1.6.2 導航守衛使用
可以利用beforeEach來完成標題的修改
首先, 我們可以在鉤子當中定義一些標題, 可以利用meta來定義。
其次, 利用導航守衛(前置鉤子hook),修改我們的標題。
執行結果
1.6.3 導航守衛補充
如果是後置鉤子, 也就是afterEach, 不需要主動呼叫next()函式。
執行結果
鉤子函式參考文件: https://router.vuejs.org/zh/guide/advanced/navigation-guards.html