這里說的Vue中的路由是指前端路由,與后端路由有所區(qū)別。我們可以使用url來獲取服務(wù)器的資源,而這種url與資源的映射關(guān)系就是我們所說的路由。對于單頁面程序來說,我們使用url時常常通過hash的方法切換頁面,即我們常用的錨點。比如:
<a href="#here">click me</a> /*跳轉(zhuǎn)到對應(yīng)的錨點*/
<!-- ... -->
<div id="here">you find me</div> /*設(shè)置錨點*/
而請求路徑中的hash不會傳到后端,所以常常被用作前端切換頁面的方法,即在同一服務(wù)器資源下對頁面進(jìn)行切換。
下面分別從Node和Vue中使用路由,來感受具體的區(qū)別。
一、使用Node中的路由:express自帶ruoter
先看一下需要完成的效果:

當(dāng)我們點擊頁面上的Home和About按鈕是會跳轉(zhuǎn)到對應(yīng)的服務(wù)器資源頁面。
首先安裝必要的模塊,創(chuàng)建文件目錄結(jié)構(gòu)和前端資源文件。
# 初始化目錄
npm init -y
# 安裝需要的模塊
npm install express art-template express-art-template
其他資源頁面可以在參考這里(可直接下載運行)
二、使用Vue中的路由:VueRouter
我們使用官方路由來創(chuàng)建一個簡單的單頁面應(yīng)用:
1、VueRouter的簡單入門
首先我們需要安裝Vue.js和VueRouter.js
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
-
html代碼
<div id="app"> <p> <router-link to="/home">Home</router-link> <router-link to="/about">About</router-link> </p> <router-view></router-view> </div>router-link是VueRouter提供的組件,默認(rèn)會創(chuàng)建一個a標(biāo)簽,并將to屬性的值作為hash值最為該鏈接的地址。router-view也是VueRouter提供的組件,用來顯示路由對應(yīng)的模板。 -
js代碼
//1、創(chuàng)建路由視圖組件:包含了模板信息 var home = {template: '<h3>This is home page!</h3>'}; var about = {template: '<h3>This is about page!</h3>'}; //2、創(chuàng)建路由規(guī)則(路由的映射關(guān)系):是一個對象數(shù)組,相當(dāng)于路由映射關(guān)系表 var routes = [ {path: '/home', component: home}, {path: '/about', component: about} ]; //3、創(chuàng)建一個路由實例 var router = new VueRouter({ routes: routes }); //4、將路由搭載到Vue實例中 new Vue({ el: '#app', router: router });
2、router-link
<router-link> 組件支持用戶在具有路由功能的應(yīng)用中 (點擊) 導(dǎo)航。
通過 to 屬性指定目標(biāo)地址,默認(rèn)渲染成帶有正確鏈接的 <a> 標(biāo)簽,可以通過配置 tag 屬性生成別的標(biāo)簽.。另外,當(dāng)目標(biāo)路由成功激活時,鏈接元素自動設(shè)置一個表示激活的 CSS 類名。
-
to(String|Location, required)to屬性規(guī)定了鏈接跳轉(zhuǎn)的路徑,所以是必須的,可以是字符串,也可以是表示路徑位置的對象。<!--將會渲染為:/home--> <router-link to="home">link</router-link> <!--也可以動態(tài)綁定--> <router-link :to="'home'"></router-link> <!--動態(tài)綁定時便可以傳入對象,以下渲染為:/home?useid=123 --> <router-link :to="{path: 'home', query: {useid: '123'}}"></router-link> -
replace默認(rèn)為false,當(dāng)設(shè)置該屬性后路由不會執(zhí)行
router.push(),而是執(zhí)行router.replace(),這樣瀏覽器的history將不會產(chǎn)生導(dǎo)航記錄。<router-link to="home" replace></router-link> -
append如果設(shè)置了該屬性,則連接會變成相對鏈接。比如從
/a處點擊了連接為/b的來鏈接,則訪問的地址將變?yōu)?code>/a/b。 -
tag指定導(dǎo)航鏈接渲染的標(biāo)簽,默認(rèn)為
a標(biāo)簽。渲染為其他標(biāo)簽后任然會監(jiān)聽點擊事件,具有導(dǎo)航效果。 -
active-class設(shè)置鏈接激活后使用的css類名,默認(rèn)值為
router-link-active,設(shè)置后默認(rèn)值任然存在。默認(rèn)值可通過路由構(gòu)造選項linkActiveClass進(jìn)行配置。 -
exact"是否激活" 默認(rèn)類名的依據(jù)是 inclusive match (全包含匹配)。舉個例子,如果當(dāng)前的路徑是
/a開頭的,那么<router-link to="/a">也會被設(shè)置 CSS 類名。 -
event(String | Array< String >)設(shè)置激活導(dǎo)航的事件。默認(rèn)為
clcik。 -
exact-active-calss配置當(dāng)鏈接被精確匹配的時候應(yīng)該激活的 class。默認(rèn)值
router-link-exact-active,該默認(rèn)值也是可以通過路由構(gòu)造函數(shù)選項linkExactActiveClass進(jìn)行全局配置的。
3、router-view
<router-view> 組件是一個 functional 組件,渲染路徑匹配到的視圖組件。<router-view> 渲染的組件還可以內(nèi)嵌自己的 <router-view>,根據(jù)嵌套路徑,渲染嵌套組件。
4、路由構(gòu)建選項
在創(chuàng)建路由是可傳入的參數(shù),上面的實例中我們傳入了路由規(guī)則信息的routes,此外還有其他參數(shù)。
-
routes(Array < routeConfig >)routes是包含路由映射關(guān)系的數(shù)組,數(shù)組的每一項都包含了一條路由映射信息。routeConfig可以包含一些信息:declare type routeConfig = { path: string, //路徑 component: componentObj,//視圖組件 name: string,//命名路由 components: {[name: string]: componentObj},//命名視圖組件 redirect: string | Location | Function, props: boolean | Object | Function, alias: string | Array<string>, children: Array<RouteConfig>, // 嵌套路由 beforeEnter: (to: Route, from: Route, next: Function) => void, meta: any, // 2.6.0+ caseSensitive: boolean,// 匹配規(guī)則是否大小寫敏感?(默認(rèn)值:false) pathToRegexpOptions: Object// 編譯正則的選項 } -
mode最開始說到的前端路由和后端路由的差別,我們可以使用
mode來配置路由的模式,有以下三種模式:-
hash:瀏覽器模式,會在鏈接前加上"#"最為倆鏈接,支持所有瀏覽器。 -
history:依賴 HTML5 History API 和服務(wù)器配置。 -
abstract:支持所有 JavaScript 運行環(huán)境,如 Node.js 服務(wù)器端。
-
-
base設(shè)置路由的基路徑,默認(rèn)為"/"。
linkActiveClasslinkExactActiveClass
此外還有一些其他可供選擇的項,這里不再一一贅述。更多細(xì)節(jié)請參考:Vue-router官方文檔
5、路由實例屬性
-
router.app:配置了該路由的Vue根實例。 -
router.mode:路由的模式。 -
router.currentRute:當(dāng)前路由對應(yīng)的路由信息對象。
6、 路由對象
一個路由對象 (route object) 表示當(dāng)前激活的路由的狀態(tài)信息,包含了當(dāng)前 URL 解析得到的信息,還有 URL 匹配到的路由記錄 (route records)。
路由對象是不可變 (immutable) 的,每次成功的導(dǎo)航后都會產(chǎn)生一個新的對象。
路由對象可以出現(xiàn)在多個地方,自如組件內(nèi):this.$route。(注意是$route而不是$router,前者是路由對象,后者是路由實例)。
路由對象有以下屬性:
- $route.path:當(dāng)前導(dǎo)航路徑。
- $route.params:一個 key/value 對象,包含了動態(tài)片段和全匹配片段,如果沒有路由參數(shù),就是一個空對象。
- $route.query:一個 key/value 對象,表示 URL 查詢參數(shù)。
-
$route.hash:當(dāng)前路由的 hash 值 (帶
#) ,如果沒有 hash 值,則為空字符串。 - $route.fullPath:完成解析后的 URL,包含查詢參數(shù)和 hash 的完整路徑。
-
$route.matched:一個數(shù)組,包含當(dāng)前路由的所有嵌套路徑片段的路由記錄 。路由記錄就是
routes配置數(shù)組中的對象副本 (還有在children數(shù)組)。 - $route.name:當(dāng)前路由的名稱,如果有的話。
- $route.redirectedFrom:如果存在重定向,即為重定向來源的路由的名字。
更多細(xì)節(jié)請參考:Vue-router官方文檔
7、一些簡單的例子
#路由對象的使用
<p>
<!--注意:這里如果沒有 / 就會變成append模式 ,即在當(dāng)前連接下添加連接-->
<router-link to="/query?id='123'&name='jinx'">Query</router-link>
<router-link to="/params/456/yasuo">Params</router-link>
</p>
<router-view></router-view>
//1、創(chuàng)建路由視圖組件:在模版中掉用路由對象
var query = {template: '<h3>this is query: id=<em>{{$route.query.id}}</em>&name=<em>{{$route.query.name}}</em></h3>'};
var params = {template: '<h3>This is params: id=<em>{{$route.params.id}}</em>, name=<em>{{$route.params.name}}</em></h3>'};
//2、創(chuàng)建路由規(guī)則
var routes = [
{path: '/query', component: query},
{path: '/params/:id/:name', component: params}
];
//3、創(chuàng)建一個路由實例
var router = new VueRouter({
routes: routes
});
//4、將路由搭載到Vue實例中
new Vue({
el: '#app',
router: router
});
#路由嵌套
<div id="app">
<!--路由-->
<router-link to="/">Home</router-link>
<router-link to="/account">Account</router-link>
<router-view></router-view>
<!--模板-->
<script type="text/template" id="account-template">
<div>
<h3>用戶操作界面</h3>
<!--子路由-->
<router-link to="/account/login">login</router-link>
<router-link to="/account/register">register</router-link>
<router-view></router-view>
</div>
</script>
</div>
//1、創(chuàng)建路由視圖組件
var home = {template: '<h3>home page</h3>'};
var account = {template: '#account-template'};//可以導(dǎo)入模板(這里使用template標(biāo)簽的使用有bug不知道什么原因)
var login = {template: '<h3>登陸</h3>'};
var register = {template: '<h3>注冊</h3>'};
//2、創(chuàng)建路由規(guī)則
var routes = [
{path: '/', component: home},
{path: '/account',
component: account,
children: [
{path: '/account/login', component: login},
{path: '/account/register', component: register}
]
},
];
//3、創(chuàng)建一個路由實例
var router = new VueRouter({
routes: routes
});
//4、將路由搭載到Vue實例中
new Vue({
el: '#app',
router: router
});
可以嘗試一下如果子路由也寫在外部routes的效果(當(dāng)寫在外部就會共用router-view標(biāo)簽)。關(guān)于模板需要注意的是,可以使用類似script這樣的標(biāo)簽來包裹模板,然后根據(jù)id進(jìn)行引用即可,另外,模板只能有一個根元素。關(guān)于模板標(biāo)簽的使用可以參考這篇文章:HTML5 template 標(biāo)簽元素簡介
#命名視圖組件
目前我們都只是用了一個router-view標(biāo)簽,如果我們需要使用多個,那我們就需要對組件進(jìn)行命名,否則無法找到要渲染的位置。注意,使用的是conponents而非component。
比如下面的例子:
<div id="app">
<!--對路由視圖進(jìn)行命名-->
<router-view></router-view>
<div style="display: flex;height: 800px;">
<router-view name="left"></router-view>
<router-view name="main"></router-view>
</div>
</div>
//1、創(chuàng)建路由視圖組件
var header = {template: '<div class="header">header</div>'};
var left = {template: '<div class="left">left</div>'};
var main = {template: '<div class="main">main</div>'};
//2、創(chuàng)建路由規(guī)則
var routes = [
{path: '/',
components: {
default: header,
left: left,
main: main
}//命名視圖組件
}];
//3、創(chuàng)建一個路由實例
var router = new VueRouter({
routes: routes
});
//4、將路由搭載到Vue實例中
new Vue({
el: '#app',
router: router
});
再添加一下樣式:
body{
margin: 0px;
padding: 0px;
}
.header{
background-color: #6aa4d2;
height: 100px;
}
.left{
background-color: #999ddd;
flex: 2;
}
.main{
background-color: #b6b985;
flex: 8;
}
就可以看到以下布局效果:
