1. 后端路由階段
早期的網站開發整個
HTML
頁面是由服務器來渲染的。服務器直接生產渲染好對應的HTML頁面, 返回給客戶端進行展示。
1.1 但是, 一個網站, 這么多頁面服務器如何處理呢?
一個頁面有自己對應的網址, 也就是
URL
。URL
會發送到服務器, 服務器會通過正則對該URL
進行匹配, 并且最后交給一個Controller
進行處理。Controller
進行各種處理, 最終生成HTML
或者數據, 返回給前端。這就完成了一個
IO
操作。
上面的這種操作, 就是后端路由,當我們頁面中需要請求不同的路徑內容時, 交給服務器來進行處理, 服務器渲染好整個頁面, 并且將頁面返回給客戶端,這種情況下渲染好的頁面, 不需要單獨加載任何的
js
和css
, 可以直接交給瀏覽器展示, 這樣也有利于SEO
的優化。
1.2 后端路由的缺點:
一種情況是整個頁面的模塊由后端人員來編寫和維護的;
另一種情況是前端開發人員如果要開發頁面, 需要通過
PHP
和Java
等語言來編寫頁面代碼;而且通常情況下HTML代碼和數據以及對應的邏輯會混在一起, 編寫和維護都是非常糟糕的事情。
2. 前端路由階段
2.1 前后端分離階段
隨著
Ajax
的出現, 有了前后端分離的開發模式。后端只提供
API
來返回數據, 前端通過Ajax
獲取數據, 并且可以通過JavaScript
將數據渲染到頁面中。這樣做最大的優點就是前后端責任的清晰, 后端專注于數據上, 前端專注于交互和可視化上。
并且當移動端
(iOS/Android)
出現后, 后端不需要進行任何處理, 依然使用之前的一套API
即可。
2.2 單頁面富應用階段
其實SPA最主要的特點就是在前后端分離的基礎上加了一層前端路由。
也就是前端來維護一套路由規則。
3. URL的hash 模式 和 HTML5 的 history 模式
3.1 URL的hash模式
-
URL
的hash
也就是錨點(#
), 本質上是改變window.location
的href
屬性;我們可以通過直接賦值location.hash
來改變href
, 但是頁面不發生刷新。
3.2 HTML5的history模式
-
history
對象的pushState
方法傳遞三個參數,第一個參數是一個對象。第二個參數是title
, 第三個參數是路徑。
-
history
模式的replaceState
方法:替換路徑,不能通過返回箭頭返回。
-
history
模式的go
方法:到某個索引的路徑下:
history.go(-1) // 表示后退一步 和 history.back() 類似
history.go(1) // 表示前進一步 和 history.forward() 類似
4. Vue-Router的安裝配置
- Vue-router是
Vue.js
官方的路由插件,它和
4.1 安裝 Vue-Router
- 安裝為一個運行時依賴:
npm install vue-router --save
創建一個
router
文件夾,并在文件中創建一個index.js
文件。在
index.js
文件中引入VueRouter
對象和Vue
對象。
import VueRouter from 'vue-router';
import Vue from 'vue';
- 通過Vue.use(傳入插件)安裝該插件,任何Vue的插件都要使用 Vue.use進行安裝。
Vue.use(VueRouter);
- 創建
VueRouter對象實例
,注意這里是 routes 而不是 routers 重要重要重要
// 路由數組
const routes = [];
// 2. 創建VueRouter對象
const router = new VueRouter({
// 配置組件之間的映射關系
// 對象屬性的簡寫
routes
});
- 導出
VueRouter
對象實例:
export default router;
- 在
main.js
中引入并使用router
:
4.2 配置路由的映射關系
- 在
components
文件夾下創建Home
和About
組件。
- 在
router/index.js
下配置路由映射關系 。
- 使用
Vue
中注冊的全局組件router-link
和router-view
實現頁面跳轉和渲染。
<div id="app">
<!-- router-link是Vue中注冊的全局組件 -->
<router-link to="/home">首頁</router-link>
<router-link to="/about">關于</router-link>
<router-view></router-view>
</div>
<router-link>
: 該標簽是一個vue-router
中已經內置的組件, 它會被渲染成一個<a>
標簽。<router-view>
: 該標簽會根據當前的路徑, 動態渲染出不同的組件。默認顯示首頁:
/home
,將進入頁面時將頁面重定向到Home
頁面
// 路由數組
const routes = [
{
path: '/',
/* 將路徑重定向到home */
redirect: '/home'
},
{
path: '/home',
name: 'Home',
component: Home
},
{
path: '/about',
component: About
}
]
4.3 修改路由的模式為 history
- 默認情況下,路徑改變使用的是
URL
的hash
,如果希望使用HTML5
的history
模式可以進行如下的修改。
// 2. 創建VueRouter對象
const router = new VueRouter({
// 配置組件之間的映射關系
// 對象屬性的簡寫 但是這個屬性必須交 routes
routes,
mode:'history'
});
4.4 router-link 的其他屬性
router-link
標簽的 tag
屬性
- 可以 通過
tag
設置router-link
使用什么標簽來進行渲染。
<!-- router-link是Vue中注冊的全局組件 -->
<router-link tag="button" to="/home">首頁</router-link>
<router-link tag="button" to="/about">關于</router-link>
router-link
標簽的 replace
屬性
-
replace
屬性設置之之后通過該標簽跳轉的路徑,不能通過瀏覽器的后退鍵返回。replace
不會留下history
記錄, 所以指定replace
的情況下, 后退鍵返回不能返回到上一個頁面中。這就說明vue-router
默認使用的是history
的pushState
。
<!-- router-link是Vue中注冊的全局組件 -->
<router-link tag="button" to="/home" replace>首頁</router-link>
<router-link tag="button" to="/about" replace>關于</router-link>
router-link
標簽的 active-class
屬性
- 默認情況下當點擊某個標簽,該標簽被激活之后,在其中會添加一個
class
,router-link-active
。可以通過該class
設置激活樣式。
.router-link-active {
color: #f00;
}
- 該
class
的名稱是可以被修改的,此時就需要在標簽中 使用active-class
屬性對class
的名稱進行修改。
<!-- router-link是Vue中注冊的全局組件 -->
<router-link tag="button" to="/home" replace active-class="active">首頁</router-link>
<router-link tag="button" to="/about" replace active-class="active">關于</router-link>
.active {
color: #00f;
}
在 router/index.js
文件的router
對象中使用linkActiveClass
屬性統一修改樣式名稱
4.5 通過代碼實現路由的跳轉
- 在頁面中定義兩個按鈕實現路由的跳轉:利用
vue
內置的$router
的push
和replace
方法實現跳轉。
<!-- 通過代碼實現路由的跳轉 -->
<button @click="btnClickHome">首頁</button>
<button @click="btnClickAbout">關于</button>
/**
* 跳轉到 首頁
*/
btnClickHome() {
// this.$router.push('/home');
this.$router.replace('/home'); // 跳轉之后不能通過瀏覽器的后退按鈕返回
},
/**
* 實現跳轉到關于
*/
btnClickAbout() {
// this.$router.push('/about');
this.$router.replace('/about'); // 跳轉之后不能通過瀏覽器的后退按鈕返回
}
5. vue-router 動態路由的使用
- 創建一個
User
組件并在router/index.js
中配置路由:
// 路由數組
const routes = [
{
path: '/',
/* 將路徑重定向到home */
redirect: '/home'
},
{
path: '/home',
name: 'Home',
component: Home
},
{
path: '/about',
component: About
},
{
path: '/user/:userId',
component: User
}
];
- 在
APP.vue
中使用router-link
配置路由實現跳轉:在配置時一并傳遞參數。
<!-- 實現動態路由 -->
<router-link to="/home">首頁</router-link>
<router-link to="/about">關于</router-link>
<!-- 在此使用動態路由 使用 v-bind 動態綁定 -->
<router-link :to="`/user/` + userId">用戶</router-link>
- 在跳轉到
User
組件之后,在User
頁面獲取到路徑中的userId
參數:這里需要通過一個$route
的屬性獲取。使用$route.params.userId
獲取。但是這里的userId
是與路由配置中的userId
一一對應的。
<div>
<h2>我是User組件</h2>
<!-- 獲取到路徑中傳遞的用戶名 的兩種方式-->
<!-- 1. 直接在Mustache語法中寫 -->
<h2>{{$route.params.userId}} 您好!</h2>
<!-- 2. 通過計算屬性的方式 -->
<h2>{{userId}} 您好!</h2>
</div>
computed: {
userId() {
return this.$route.params.userId
}
}
6. vue-router 打包文件的解析
7. 路由的懶加載
路由懶加載的官方解釋:首先, 我們知道路由中通常會定義很多不同的頁面,這個頁面最后被打包在哪里呢? 一般情況下, 是放在一個
js
文件中,但是, 頁面這么多放在一個js
文件中, 必然會造成這個頁面非常的大,
如果我們一次性從服務器請求下來這個頁面, 可能需要花費一定的時間, 甚至用戶的電腦上還出現了短暫空白的情況。路由懶加載做了什么? 答: 路由懶加載的主要作用就是將路由對應的組件打包成一個個的
js
代碼塊。只有在這個路由被訪問到的時候, 才加載對應的組件。
7.2 各種路由懶加載的配置方式
- 方式一: 結合
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')
8. 認識路由的嵌套
8.1 嵌套路由配置案例
- 創建一個
HomeMessage
和HomeNews
組件。
<template>
<div>
<ul>
<li>消息1</li>
<li>消息2</li>
<li>消息3</li>
<li>消息4</li>
</ul>
</div>
</template>
<script>
export default {
name: "home-message"
}
</script>
<style scoped>
</style>
<template>
<div>
<ul>
<li>新聞1</li>
<li>新聞2</li>
<li>新聞3</li>
<li>新聞4</li>
</ul>
</div>
</template>
<script>
export default {
name: "home-news"
}
</script>
<style scoped>
</style>
- 配置嵌套路由 :
/* 使用懶加載的方式加載組件 */
const Home = () => import('../components/Home')
const HomeNews = () => import('../components/HomeNews')
const HomeMessage = () => import('../components/HomeMessage')
const About = () => import('../components/About')
const User = () => import('../components/User')
// 1. 通過Vue.use(傳入插件)安裝該插件,任何Vue的插件都要使用 Vue.use進行安裝
Vue.use(VueRouter);
// 路由數組
const routes = [
{
path: '/',
/* 將路徑重定向到home */
redirect: '/home'
},
{
path: '/home',
name: 'Home',
component: Home,
/* 配置路由的嵌套 */
children:[
/* 配置默認顯示首頁的時候一并顯示消息 */
{
path:'/',
redirect:'news'
}
,
{
/* 注意這里沒有 斜杠 / 這里是不能有 斜杠的 */
path:'news',
component:HomeNews
},
{
path:'message',
component:HomeMessage
}
]
},
{
path: '/about',
component: About
},
{
path: '/user/:userId',
component: User
}
];
- 因為這兩個組件需要在
Home
組件中切換顯示,所以還需在Home
組件中使用router-link
和router-view
進行配置。
<template>
<div>
<h2>我是Home組件</h2>
<router-link to="/home/news">新聞</router-link>
<router-link to="/home/message">消息</router-link>
<router-view></router-view>
</div>
</template>
9. vue-router 參數傳遞
9.1 參數傳遞的方式一 user/:userId
9.2 參數傳遞的方式二 query參數對象傳遞案例
- 創建一個新的組件
Profile
<template>
<div>
<h2>我是Profile組件</h2>
</div>
</template>
<script>
export default {
name: "profile"
}
</script>
<style scoped>
</style>
- 為組件配置路由 :
- 使用
router-link
的方式實現路由的跳轉并傳遞query
參數對象。
- 使用觸發事件的方式實現路由的跳轉:通過
this.$router.push(``)
的方式實現路由跳轉。
10. vue-router 和 vue-route 是由區別的
$router
為VueRouter
實例,想要導航到不同URL
,則使用$router.push
方法。$route
為當前router
跳轉對象里面可以獲取name、path、query、params
等。
11. 導航守衛
1.有時可能需要在跳轉過程之間做一些新的操作。就可以使用導航守衛監聽跳轉過程。
-
URL組成:
URL= scheme(協議)://host(主機):port(端口)/path(路徑)?query(查詢)#fragment(片段)
;
11.1 當頁面跳轉的時候如果需要改變 title 該如何做?
網頁標題是通過
<title>
來顯示的, 但是SPA
只有一個固定的HTML
, 切換不同的頁面時, 標題并不會改變。但是我們可以通過
JavaScript
來修改<title>
的內容window.document.title = '新的標題'
。
- 那么在
Vue
項目中, 在哪里修改? 什么時候修改比較合適呢?
使用導航守衛在路由跳轉前進行修改頁面 title
操作
使用
router
實例對象的beforeEach
方法前置守衛函數,函數中傳遞一個鉤子函數,鉤子函數需要 3 個參數。to , from ,next
。需要向下執行就需要調用next()
。在執行
next()
之前將title
進行修改。但是動態的title
從哪里來呢?
11.2 導航守衛的分類
全局路由守衛;
路由獨享守衛;
組件內守衛。
參考。
12. vue-router 的 keep-alive
-
keep-alive
是一個標簽,是一個保持組件為活躍狀態,不會被頻繁的創建和頻繁的銷毀。
12.1 利用 keep-alive 和 activated 、beforeRouteLeave 導航守衛實現記住上一個頁面的選擇案例
- 當
router-view
標簽外面包裹了keep-alive
標簽之后activated
方法就會有效:在該方法中實現路由的跳轉。
- 當離開當前的組件之前記錄一下當前的路徑
path
。
在beforeRouteLeave方法中就是離開組件之前記住上次的路徑
只有使用 keep-alive標簽包裹的組件使用 activated 和 deactived 才是有效的。
12.2 keep-alive的其他屬性
keep-alive
是 Vue
內置的一個組件,可以使被包含的組件保留狀態,或避免重新渲染。
include
: 字符串或正則表達,只有匹配的組件會被緩存;exclude
: 字符串或正則表達式,任何匹配的組件都不會被緩存;
<!-- 但是中間不要隨便加空格 -->
<keep-alive exclude="profile,User">
<router-view></router-view>
</keep-alive>