零、傳統路由與SPA的區別
- 傳統開發方式下,URL改變后,就會立刻發生請求去請求整個頁面,這樣可能請求加載的資源過多,可能會讓頁面出現白屏。
- 在SPA(Single Page Application)單頁面應用下,當錨點值改變后,不會立刻發生請求,而是在某個合適的時機,發起ajax請求,實現局部改變頁面的數據。優點是:不是整個頁面發生跳轉,那么用戶的體驗就更好了。
一、vue-router的使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
</div>
<!-- 1. 先引入vue.js(被vue-router所依賴)-->
<script src="../node_modules/vue/dist/vue.js"></script>
<!-- 2. 再引入插件vue-router(使用npm install vue-router --save安裝到相應的文件夾下)-->
<script src="../node_modules/vue-router/dist/vue-router.js"></script>
<script>
/* 演示示例:頁面里有2個a標簽,注冊和登錄,點擊注冊、登錄返回不同的內容,
且有公共內容(主頁公共數據),來實現局部頁面的跳轉且URL要發生相應的改變。
*/
// 3. 讓vue使用VueRouter創建(某些情況下可以不用,這里暫且加上)
Vue.use(VueRouter);
// 聲明使用了路由的組件
var Login = {
template: `
<div>我是登錄頁面</div>
`
};
var Register = {
template: `<div>我是注冊頁面</div>`,
};
// 4. 創建VueRouter對象
var router = new VueRouter({
// 5. 配置路由對象的規則如匹配路徑、組件等
routes: [
{
path: '/login',
component: Login
},
{
path: '/register',
component: Register
}
]
});
// 當使用了vue-router后就會拋出兩個全局的組件:router-link、router-view
// router-link相當於a標簽,router-view是路由組件渲染的出口
// 聲明入口組件App
var App = {
template: `
<div>
我是公共內容<br/>
<router-link to='/login'>登錄</router-link>
<router-link to='/register'>注冊</router-link>
<router-view></router-view>
</div>
`,
};
new Vue({
el: '#app',
// 5. 將配置后的路由對象關聯到vue實例化對象中
router: router,
template: `<App />`,
components: {
App
}
});
</script>
</body>
</html>
命名路由
路由也可以擁有自己的名字,上面的例子也可以改寫為下面:
routes: [
{
path: '/login',
name: 'login',
component: Login
},
{
path: '/register',
name: 'register',
component: Register
}
]
...
<router-link :to='{name:"login"}'>登錄</router-link>
<router-link :to='{name:"register"}'>注冊</router-link>
路由參數
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script src="../node_modules/vue-router/dist/vue-router.js"></script>
<script>
/*
路由參數的使用:常見的路由范式有以下2種:
- xxx.html/user/1 params 動態路由參數(restful風格)
- xxx.html/user?userId=1 query 查詢參數
*/
Vue.use(VueRouter);
// 聲明使用了路由的組件
var Login = {
template: `
<div>我是登錄頁面</div>
`
};
var Register = {
template: `<div>我是注冊頁面</div>`,
};
var router = new VueRouter({
routes: [
{
// 動態路由參數以冒號開頭
path: '/login/:id',
name: 'login',
component: Login
},
{
// query參數在這里不做修改
path: '/register',
name: 'register',
component: Register
}
]
});
// 聲明入口組件App
var App = {
template: `
<div>
我是公共內容<br/>
<router-link :to = "{name:'login',params:{'id':1}}">登錄params</router-link>
<router-link :to = "{name:'register',query:{'userId':2}}">注冊query</router-link>
<router-view></router-view>
</div>
`,
};
new Vue({
el: '#app',
router: router,
template: `<App />`,
components: {
App
}
});
</script>
</body>
</html>
二、嵌套路由、動態路由
掘金就是由vue寫的,接下來的這個demo會模仿掘金首頁的構成,實現嵌套路由、動態路由匹配功能。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>掘金</title>
</head>
<body>
<div id="app">
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script src="../node_modules/vue-router/dist/vue-router.js"></script>
<script>
Vue.use(VueRouter);
//第二層路由組件,實現了嵌套的路由組件
// 這一層的三個路由組件:推薦、后端、前端可以看成結構是相同的,只有數據不同
// 所以為了提高代碼的復用性,就需要采用動態路由匹配的方式,及只創建一個組件,然后替換里面的數據
var Home = {
template: `
<div>
<router-link :to="{name:'category', params:{category:'recommened'}}">推薦</router-link>
<router-link :to="{name:'category', params:{category:'backend'}}">后端</router-link>
<router-link :to="{name:'category', params:{category:'fronted'}}">前端</router-link>
<router-view></router-view>
</div>
`
};
var Pins = {
template: `<div>我是沸點</div>`
};
var Topics = {
template: `<div>我是話題</div>`
};
// 創建一個組件,然后使用動態路由匹配的方式
var Commons = {
data() {
return {
msg: 'recommened'
}
},
template: `
<div>
我是 {{ msg }}
</div>
`,
watch: {
// 利用watch偵聽器來監聽$route來檢測動態路由的切換
'$route' (to, from) {
console.log(to.params.category);
// 模擬路由的變化引起的數據的變化
this.msg = to.params.category;
}
}
};
var router = new VueRouter({
routes: [
{
path: '/',
component: Home,
// 嵌套路由的寫法:
children: [
{
path: 'welcome/:category',
name: 'category',
component: Commons
}
]
},
{
path: '/pins',
component: Pins
},
{
path: '/topics',
component: Topics
}
]
});
// 第一層路由組件包括首頁、沸點、話題等
var FRouter = {
template:`
<div>
第一層路由組件
<router-link to="/">首頁</router-link>
<router-link to="/pins">沸點</router-link>
<router-link to="/topics">話題</router-link>
<router-view></router-view>
</div>
`
};
new Vue({
el: '#app',
router: router,
template: '<FRouter />',
components: {
FRouter
}
});
</script>
</body>
</html>