這里說的Vue中的路由是指前端路由,與后端路由有所區(qū)別。我們可以使用url來獲取服務器的資源篙贸,而這種url與資源的映射關系就是我們所說的路由颊艳。對于單頁面程序來說茅特,我們使用url時常常通過hash
的方法切換頁面,即我們常用的錨點棋枕。比如:
<a href="#here">click me</a> /*跳轉到對應的錨點*/
<!-- ... -->
<div id="here">you find me</div> /*設置錨點*/
而請求路徑中的hash不會傳到后端白修,所以常常被用作前端切換頁面的方法,即在同一服務器資源下對頁面進行切換重斑。
下面分別從Node和Vue中使用路由兵睛,來感受具體的區(qū)別。
一窥浪、使用Node中的路由:express自帶ruoter
先看一下需要完成的效果:
當我們點擊頁面上的Home和About按鈕是會跳轉到對應的服務器資源頁面祖很。
首先安裝必要的模塊,創(chuàng)建文件目錄結構和前端資源文件漾脂。
# 初始化目錄
npm init -y
# 安裝需要的模塊
npm install express art-template express-art-template
其他資源頁面可以在參考這里(可直接下載運行)
二假颇、使用Vue中的路由:VueRouter
我們使用官方路由來創(chuà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
提供的組件骨稿,默認會創(chuàng)建一個a
標簽笨鸡,并將to
屬性的值作為hash
值最為該鏈接的地址。router-view
也是VueRouter
提供的組件坦冠,用來顯示路由對應的模板形耗。 -
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ī)則(路由的映射關系):是一個對象數(shù)組激涤,相當于路由映射關系表 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>
組件支持用戶在具有路由功能的應用中 (點擊) 導航送滞。
通過 to
屬性指定目標地址,默認渲染成帶有正確鏈接的 <a>
標簽硼一,可以通過配置 tag
屬性生成別的標簽.累澡。另外,當目標路由成功激活時般贼,鏈接元素自動設置一個表示激活的 CSS 類名愧哟。
-
to
(String|Location, required)to
屬性規(guī)定了鏈接跳轉的路徑,所以是必須的哼蛆,可以是字符串蕊梧,也可以是表示路徑位置的對象。<!--將會渲染為:/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
默認為false腮介,當設置該屬性后路由不會執(zhí)行
router.push()
肥矢,而是執(zhí)行router.replace()
,這樣瀏覽器的history將不會產(chǎn)生導航記錄叠洗。<router-link to="home" replace></router-link>
-
append
如果設置了該屬性甘改,則連接會變成相對鏈接。比如從
/a
處點擊了連接為/b
的來鏈接灭抑,則訪問的地址將變?yōu)?code>/a/b十艾。 -
tag
指定導航鏈接渲染的標簽,默認為
a
標簽腾节。渲染為其他標簽后任然會監(jiān)聽點擊事件忘嫉,具有導航效果。 -
active-class
設置鏈接激活后使用的css類名案腺,默認值為
router-link-active
庆冕,設置后默認值任然存在。默認值可通過路由構造選項linkActiveClass
進行配置劈榨。 -
exact
"是否激活" 默認類名的依據(jù)是 inclusive match (全包含匹配)访递。舉個例子,如果當前的路徑是
/a
開頭的同辣,那么<router-link to="/a">
也會被設置 CSS 類名拷姿。 -
event
(String | Array< String >)設置激活導航的事件。默認為
clcik
邑闺。 -
exact-active-calss
配置當鏈接被精確匹配的時候應該激活的 class跌前。默認值
router-link-exact-active
棕兼,該默認值也是可以通過路由構造函數(shù)選項linkExactActiveClass
進行全局配置的陡舅。
3、router-view
<router-view>
組件是一個 functional 組件伴挚,渲染路徑匹配到的視圖組件靶衍。<router-view>
渲染的組件還可以內嵌自己的 <router-view>
灾炭,根據(jù)嵌套路徑,渲染嵌套組件颅眶。
4蜈出、路由構建選項
在創(chuàng)建路由是可傳入的參數(shù),上面的實例中我們傳入了路由規(guī)則信息的routes
涛酗,此外還有其他參數(shù)铡原。
-
routes
(Array < routeConfig >)routes
是包含路由映射關系的數(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ī)則是否大小寫敏感燕刻?(默認值:false) pathToRegexpOptions: Object// 編譯正則的選項 }
-
mode
最開始說到的前端路由和后端路由的差別,我們可以使用
mode
來配置路由的模式剖笙,有以下三種模式:-
hash
:瀏覽器模式卵洗,會在鏈接前加上"#"最為倆鏈接,支持所有瀏覽器弥咪。 -
history
:依賴 HTML5 History API 和服務器配置过蹂。 -
abstract
:支持所有 JavaScript 運行環(huán)境,如 Node.js 服務器端聚至。
-
-
base
設置路由的基路徑酷勺,默認為"/"。
linkActiveClass
linkExactActiveClass
此外還有一些其他可供選擇的項晚岭,這里不再一一贅述鸥印。更多細節(jié)請參考:Vue-router官方文檔
5、路由實例屬性
-
router.app
:配置了該路由的Vue根實例坦报。 -
router.mode
:路由的模式库说。 -
router.currentRute
:當前路由對應的路由信息對象。
6片择、 路由對象
一個路由對象 (route object) 表示當前激活的路由的狀態(tài)信息潜的,包含了當前 URL 解析得到的信息,還有 URL 匹配到的路由記錄 (route records)字管。
路由對象是不可變 (immutable) 的啰挪,每次成功的導航后都會產(chǎn)生一個新的對象。
路由對象可以出現(xiàn)在多個地方嘲叔,自如組件內:this.$route
亡呵。(注意是$route
而不是$router
,前者是路由對象硫戈,后者是路由實例)锰什。
路由對象有以下屬性:
- $route.path:當前導航路徑。
- $route.params:一個 key/value 對象,包含了動態(tài)片段和全匹配片段汁胆,如果沒有路由參數(shù)梭姓,就是一個空對象。
- $route.query:一個 key/value 對象嫩码,表示 URL 查詢參數(shù)誉尖。
-
$route.hash:當前路由的 hash 值 (帶
#
) ,如果沒有 hash 值铸题,則為空字符串铡恕。 - $route.fullPath:完成解析后的 URL,包含查詢參數(shù)和 hash 的完整路徑丢间。
-
$route.matched:一個數(shù)組没咙,包含當前路由的所有嵌套路徑片段的路由記錄 。路由記錄就是
routes
配置數(shù)組中的對象副本 (還有在children
數(shù)組)千劈。 - $route.name:當前路由的名稱祭刚,如果有的話。
- $route.redirectedFrom:如果存在重定向墙牌,即為重定向來源的路由的名字涡驮。
更多細節(jié)請參考:Vue-router官方文檔
7、一些簡單的例子
#路由對象的使用
<p>
<!--注意:這里如果沒有 / 就會變成append模式 喜滨,即在當前連接下添加連接-->
<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'};//可以導入模板(這里使用template標簽的使用有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
的效果(當寫在外部就會共用router-view
標簽)厂抖。關于模板需要注意的是茎毁,可以使用類似script
這樣的標簽來包裹模板,然后根據(jù)id進行引用即可忱辅,另外七蜘,模板只能有一個根元素。關于模板標簽的使用可以參考這篇文章:HTML5 template 標簽元素簡介
#命名視圖組件
目前我們都只是用了一個router-view
標簽墙懂,如果我們需要使用多個橡卤,那我們就需要對組件進行命名,否則無法找到要渲染的位置损搬。注意碧库,使用的是conponents
而非component
扔亥。
比如下面的例子:
<div id="app">
<!--對路由視圖進行命名-->
<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;
}
就可以看到以下布局效果: