路由概念
路由的本質就是一種對應關系,比如說我們在url地址中輸入我們要訪問的url地址之后,瀏覽器要去請求這個url地址對應的資源。
那么url地址和真實的資源之間就有一種對應的關系,就是路由。
路由分為前端路由和后端路由
/*
1).后端路由是由服務器端進行實現,並完成資源的分發.
概念: 根據不同的URL請求,返回不同的內容
本質: URL請求地址與服務器資源之間的對應關系
2).前端路由是依靠hash值(錨鏈接)的變化進行實現
概念: 根據不同的事件顯示不同的頁面內容,即事件與事件處理函數之間的對應關系.
前端路由主要做監聽事件並分發執行事件處理函數
后端路由性能相對前端路由來說較低
*/
SPA
Single Page Application
/*
后端渲染(存在性能問題)
Ajax前端渲染(前端渲染提高性能,但是不支持瀏覽器的前進后退操作)
SPA(Single Page Applicationn) 單頁面應用程序:
整個網站只有一個頁面,內容的變化通過Ajax局部更新實現,同時支持瀏覽器地址欄的前進和后退操作.
SPA實現原理之一: 基於URL地址的hash(hash的變化會導致瀏覽器記錄訪問歷史的變化,但是hash的變化不會觸發新的URL請求)
在實現SPA的過程中,最核心技術點就是前端路由
*/
前端路由
前端路由是基於hash值的變化進行實現的(比如點擊頁面中的菜單或者按鈕改變URL的hash值,根據hash值的變化來控制組件的切換)
核心實現依靠一個不同的用戶事件,即監聽hash值變化的事件,顯示不同的頁面內容.
本質: 用戶事件與事件處理函數之間的對應關系
實現簡易前端路由
基於URL的hash實現(點擊菜單的時候改變URL的hash,根據hash的變化控制組件的切換)
模擬路由
<!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>
<!-- 導入 vue 文件 -->
<script src="./js/vue_2.5.22.js"></script>
</head>
<body>
<!-- 被 vue 實例控制的 div 區域 -->
<div id="app">
<!-- 切換組件的超鏈接 -->
<a href="#/zhuye">主頁</a>
<a href="#/keji">科技</a>
<a href="#/caijing">財經</a>
<a href="#/yule">娛樂</a>
<!-- 根據 :is 屬性指定的組件名稱,把對應的組件渲染到 component 標簽所在的位置 -->
<!-- 可以把 component 標簽當做是【組件的占位符】 -->
<component :is="comName"></component>
</div>
<script>
// #region 定義需要被切換的 4 個組件
// 主頁組件
const zhuye = {
template: '<h1>主頁信息</h1>'
}
// 科技組件
const keji = {
template: '<h1>科技信息</h1>'
}
// 財經組件
const caijing = {
template: '<h1>財經信息</h1>'
}
// 娛樂組件
const yule = {
template: '<h1>娛樂信息</h1>'
}
// #endregion
// #region vue 實例對象
const vm = new Vue({
el: '#app',
data: {
comName: 'zhuye'
},
// 注冊私有組件
components: {
zhuye,
keji,
caijing,
yule
}
})
// #endregion
// 監聽 window 的 onhashchange 事件,根據獲取到的最新的 hash 值,切換要顯示的組件的名稱
window.onhashchange = function () {
// 通過 location.hash 獲取到最新的 hash 值
console.log(location.hash);
switch (location.hash.slice(1)) {
case '/zhuye':
vm.comName = 'zhuye'
break
case '/keji':
vm.comName = 'keji'
break
case '/caijing':
vm.comName = 'caijing'
break
case '/yule':
vm.comName = 'yule'
break
}
}
</script>
</body>
</html>
核心思路
在頁面中有一個vue實例對象,vue實例對象中有四個組件,分別是tab欄切換需要顯示的組件內容
在頁面中有四個超鏈接,如下:
<a href="#/zhuye">主頁</a>
<a href="#/keji">科技</a>
<a href="#/caijing">財經</a>
<a href="#/yule">娛樂</a>
當我們點擊這些超鏈接的時候,就會改變url地址中的hash值,當hash值被改變時,就會觸發onhashchange事件
在觸發onhashchange事件的時候,我們根據hash值來讓不同的組件進行顯示:
window.onhashchange = function() {
// 通過 location.hash 獲取到最新的 hash 值
console.log(location.hash);
switch(location.hash.slice(1)){
case '/zhuye':
//通過更改數據comName來指定顯示的組件
//因為 <component :is="comName"></component> ,組件已經綁定了comName
vm.comName = 'zhuye'
break
case '/keji':
vm.comName = 'keji'
break
case '/caijing':
vm.comName = 'caijing'
break
case '/yule':
vm.comName = 'yule'
break
}
}
Vue Router簡介
它是一個Vue.js官方提供的路由管理器。是一個功能更加強大的前端路由器,推薦使用。
Vue Router和Vue.js非常契合,可以一起方便的實現SPA(single page web application,單頁應用程序)應用程序的開發。
Vue Router依賴於Vue,所以需要先引入Vue,再引入Vue Router
Vue Router特性
/*
支持H5歷史模式或者hash模式
支持嵌套路由
支持路由參數
支持編程式路由
支持命名路由
支持路由導航守衛
支持路由過渡動畫特效
支持路由懶加載
支持路由滾動行為
*/
Vue Router的使用
步驟
/*
1. 引入相關的庫文件
2. 添加路由鏈接
3. 添加路由填充位
4. 定義路由組件
5. 配置路由規則並創建路由實例
6. 把路由掛載到Vue根實例中
補充:
路由重定向:可以通過路由重定向為頁面設置默認展示的組件
在路由規則中添加一條路由規則即可,如下:
var myRouter = new VueRouter({
//routes是路由規則數組
routes: [
//path設置為/表示頁面最初始的地址 / ,redirect表示要被重定向的新地址,設置為一個路由即可
{ path:"/",redirect:"/user"},
{ path: "/user", component: User },
{ path: "/login", component: Login }
]
})
*/
A.導入js文件
<script src="lib/vue_2.5.22.js"></script>
<script src="lib/vue-router_3.0.2.js"></script>
B.添加路由鏈接:<router-link>是路由中提供的標簽,默認會被渲染為a標簽,to屬性默認被渲染為href屬性, to屬性的值會被渲染為#開頭的hash地址
<router-link to="/user">User</router-link>
<router-link to="/login">Login</router-link>
C.添加路由填充位(路由占位符)
<!-- 路由填充位(也叫路由占位符) -->
<!-- 將來通過路由規則匹配到的組件, 將會被渲染到router-view所在的位置 -->
<router-view></router-view>
D.定義路由組件
var User = { template:"<div>This is User</div>" }
var Login = { template:"<div>This is Login</div>" }
E.配置路由規則並創建路由實例
var myRouter = new VueRouter({
//routes是路由規則數組
routes:[
//每一個路由規則都是一個對象,對象中至少包含path和component兩個屬性
//path表示 路由匹配的hash地址,component表示路由規則對應要展示的組件對象
{path:"/user",component:User},
{path:"/login",component:Login}
]
})
F.將路由掛載到Vue實例中
new Vue({
el:"#app",
//通過router屬性掛載路由對象
router:myRouter
})
Example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript" src="js/vue-router_3.0.2.js"></script>
</head>
<body>
<body>
<!-- 被 vm 實例所控制的區域 -->
<div id="app">
<router-link to="/user">User</router-link>
<router-link to="/register">Register</router-link>
<!-- 路由占位符 -->
<router-view></router-view>
</div>
<script>
const User = {
template: '<h1>User 組件</h1>'
}
const Register = {
template: '<h1>Register 組件</h1>'
}
// 創建路由實例對象
const router = new VueRouter({
// 所有的路由規則
routes: [
{path: '/user', component: User},
{path: '/register', component: Register}
]
})
// 創建 vm 實例對象
const vm = new Vue({
// 指定控制的區域
el: '#app',
data: {},
// 掛載路由實例對象
// router: router
router
})
</script>
</body>
</html>
路由重定向
路由重定向指的是: 用戶在訪問A的時候,強制用戶跳轉到地址c,從而展示特定的組件頁面;
通過路由規則的redirect屬性,指定一個新的路由地址,可以很方便的設置路由重定向.
// 創建路由實例對象
var router = new VueRouter({
// 所有的路由規則
routes: [
// 其中,path表示需要被重定向的原地址, redirect表示將要被重定向到的新地址
{path: '/', redirect: '/User'},
{path: '/user', component: '/User'},
{path: '/register', component: Register}
]
})
嵌套路由
嵌套路由功能
/*
點擊父級路由鏈接顯示模板內容
模板內容中又有子級路由鏈接
點擊子級路由鏈接顯示子級模板內容
*/
嵌套路由的概念
當我們進行路由的時候顯示的組件中還有新的子級路由鏈接以及內容。
嵌套路由最關鍵的代碼在於理解子級路由的概念:
比如我們有一個/login的路由
那么/login下面還可以添加子級路由,如:
/login/account
/login/phone
參考代碼如下
var User = { template: "<div>This is User</div>" }
//Login組件中的模板代碼里面包含了子級路由鏈接以及子級路由的占位符
var Login = { template: `<div>
<h1>This is Login</h1>
<hr>
<router-link to="/login/account">賬號密碼登錄</router-link>
<router-link to="/login/phone">掃碼登錄</router-link>
<!-- 子路由組件將會在router-view中顯示 -->
<router-view></router-view>
</div>` }
//定義兩個子級路由組件
var account = { template:"<div>賬號:<input><br>密碼:<input></div>"};
var phone = { template:"<h1>掃我二維碼</h1>"};
var myRouter = new VueRouter({
//routes是路由規則數組
routes: [
{ path:"/",redirect:"/user"},
{ path: "/user", component: User },
{
path: "/login",
component: Login,
//通過children屬性為/login添加子路由規則
children:[
{ path: "/login/account", component: account },
{ path: "/login/phone", component: phone },
]
}
]
})
var vm = new Vue({
el: '#app',
data: {},
methods: {},
router:myRouter
});
嵌套路由用法
父路由組件模板
/*
父級路由鏈接
父組件路由填充位
*/
<p>
<router-link to="/user">User</router-link>
<router-link to="/register">Register</router-link>
</p>
<div>
<!-- 控制組件的顯示位置 -->
<router-view></router-view>
</div>
子級路由模板
/*
子級路由鏈接
子級路由填充位
*/
const Register = {
template: `<div>
<h1>Register 組件</h1>
<hr/>
<router-link to="/register/tab1">Tab1</router-link>
<router-link to="/register/tab2">Tab2</router-link>
<!-- 子路由填充位置 -->
<router-view/>
</div>
}
父路由通過children屬性配置子級路由
const router = new VueRouteer({
routes: [
{ path: '/user',component: User},
{
path: '/register',
component: Register,
// 通過children屬性,為/register添加子路由規則
children: [
{path: '/',redirect: '/user'},
{path: '/user', component: User},
{path: '/register', component: Register}
]
}
]
})
Example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript" src="js/vue-router_3.0.2.js"></script>
</head>
<body>
<body>
<!-- 被 vm 實例所控制的區域 -->
<div id="app">
<router-link to="/user">User</router-link>
<router-link to="/register">Register</router-link>
<!-- 路由占位符 -->
<router-view></router-view>
</div>
<script>
const User = {
template: '<h1>User 組件</h1>'
}
const Register = {
template: `
<div>
<h1>Register 組件</h1>
<hr/>
<router-link to="/register/tab1">tab1</router-link>
<router-link to="/register/tab2">tab2</router-link>
<router-view/>
</div>`
}
const Tab1 = {
template: '<h3>tab1 子組件</h3>'
}
const Tab2 = {
template: '<h3>tab2 子組件</h3>'
}
// 創建路由實例對象
const router = new VueRouter({
// 所有的路由規則
routes: [
{path: '/', redirect: '/user'},
{path: '/user', component: User},
// children 數組表示子路由規則
{
path: '/register', component: Register, children: [
{path: '/register/tab1', component: Tab1},
{path: '/register/tab2', component: Tab2}
]
}
]
})
// 創建 vm 實例對象
const vm = new Vue({
// 指定控制的區域
el: '#app',
data: {},
// 掛載路由實例對象
// router: router
router
})
</script>
</body>
</html>
動態路由
動態路由匹配
var User = { template:"<div>用戶:{{$route.params.id}}</div>"}
var myRouter = new VueRouter({
//routes是路由規則數組
routes: [
//通過/:參數名 的形式傳遞參數
{ path: "/user/:id", component: User },
]
})
注意
// 如果使用$route.params.id來獲取路徑傳參的數據不夠靈活。
// 1.我們可以通過props來接收參數
var User = {
props:["id"],
template:"<div>用戶:{{id}}</div>"
}
var myRouter = new VueRouter({
//routes是路由規則數組
routes: [
//通過/:參數名 的形式傳遞參數
//如果props設置為true,route.params將會被設置為組件屬性
{ path: "/user/:id", component: User,props:true },
]
})
// 2.還有一種情況,我們可以將props設置為對象,那么就直接將對象的數據傳遞給
組件進行使用
var User = {
props:["username","pwd"],
template:"<div>用戶:{{username}}---{{pwd}}</div>"
}
var myRouter = new VueRouter({
//routes是路由規則數組
routes: [
//通過/:參數名 的形式傳遞參數
//如果props設置為對象,則傳遞的是對象中的數據給組件
{ path: "/user/:id", component: User,props:{username:"jack",pwd:123} },
]
})
// 3.如果想要獲取傳遞的參數值還想要獲取傳遞的對象數據,那么props應該設置為
函數形式。
var User = {
props:["username","pwd","id"],
template:"<div>用戶:{{id}} -> {{username}}---{{pwd}}</div>"
}
var myRouter = new VueRouter({
//routes是路由規則數組
routes: [
//通過/:參數名 的形式傳遞參數
//如果props設置為函數,則通過函數的第一個參數獲取路由對象
//並可以通過路由對象的params屬性獲取傳遞的參數
//
{ path: "/user/:id", component: User,props:(route)=>{
return {username:"jack",pwd:123,id:route.params.id}
}
},
]
})
Example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript" src="js/vue-router_3.0.2.js"></script>
</head>
<body>
<body>
<!-- 被 vm 實例所控制的區域 -->
<div id="app">
<router-link to="/user/1">User1</router-link>
<router-link to="/user/2">User2</router-link>
<router-link to="/user/3">User3</router-link>
<router-link to="/register">Register</router-link>
<!-- 路由占位符 -->
<router-view></router-view>
</div>
<script>
const User = {
template: '<h1>User 組件 -- 用戶id為: {{ $route.params.id }}</h1>'
}
const Register = {
template: `
<div>
<h1>Register 組件</h1>
<hr/>
<router-link to="/register/tab1">tab1</router-link>
<router-link to="/register/tab2">tab2</router-link>
<router-view/>
</div>`
}
const Tab1 = {
template: '<h3>tab1 子組件</h3>'
}
const Tab2 = {
template: '<h3>tab2 子組件</h3>'
}
// 創建路由實例對象
const router = new VueRouter({
// 所有的路由規則
routes: [
{path: '/', redirect: '/user'},
{path: '/user/:id', component: User},
// children 數組表示子路由規則
{
path: '/register', component: Register, children: [
{path: '/register/tab1', component: Tab1},
{path: '/register/tab2', component: Tab2}
]
}
]
})
// 創建 vm 實例對象
const vm = new Vue({
// 指定控制的區域
el: '#app',
data: {},
// 掛載路由實例對象
// router: router
router
})
</script>
</body>
</html>
路由組件傳遞參數
/*
$route與對應路由形式高度耦合,不夠靈活,所以可以使用props將組件和路由解耦
*/
1. props的值為布爾類型
const router = new VueRouter({
routes: [
// 如果props被設置為true, route.params將會被設置為組件屬性
[ path: '/user/:id',component: User,props:true ]
]
const User = [
props: ['id'], // 使用props接受路由參數
template: '<div>用戶ID: {{ id }}</div>' // 使用路由參數
]
})
Example1
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript" src="js/vue-router_3.0.2.js"></script>
</head>
<body>
<body>
<!-- 被 vm 實例所控制的區域 -->
<div id="app">
<router-link to="/user/1">User1</router-link>
<router-link to="/user/2">User2</router-link>
<router-link to="/user/3">User3</router-link>
<router-link to="/register">Register</router-link>
<!-- 路由占位符 -->
<router-view></router-view>
</div>
<script>
const User = {
props: ['id'],
template: '<h1>User 組件 -- 用戶id為: {{ id }}</h1>'
}
const Register = {
template: `
<div>
<h1>Register 組件</h1>
<hr/>
<router-link to="/register/tab1">tab1</router-link>
<router-link to="/register/tab2">tab2</router-link>
<router-view/>
</div>`
}
const Tab1 = {
template: '<h3>tab1 子組件</h3>'
}
const Tab2 = {
template: '<h3>tab2 子組件</h3>'
}
// 創建路由實例對象
const router = new VueRouter({
// 所有的路由規則
routes: [
{path: '/', redirect: '/user'},
{path: '/user/:id', component: User, props: true},
// children 數組表示子路由規則
{
path: '/register', component: Register, children: [
{path: '/register/tab1', component: Tab1},
{path: '/register/tab2', component: Tab2}
]
}
]
})
// 創建 vm 實例對象
const vm = new Vue({
// 指定控制的區域
el: '#app',
data: {},
// 掛載路由實例對象
// router: router
router
})
</script>
</body>
</html>
props的值為對象類型
const router = new VueRouter({
routes: [
// 如果props被設置為true, route.params將會被設置為組件屬性
[ path: '/user/:id',component: User,props: {uname:'lisi',age:12} ]
]
const User = [
props: ['uname','age'], // 使用props接受路由參數
template: '<div>用戶ID: {{ uname + '----' + age }}</div>' // 使用路由參數
]
})
props的值為函數類型
const router = new VueRouter({
routes: [
// 如果props是一個函數,則這個函數接受route對象為自己的形參
[ path: '/user/:id',component: User,props: route => ({uname: 'zs',age: 20, id: route.params.id})
]
})
const User = [
props: ['uname','age','id'], // 使用props接受路由參數
template: '<h1>User 組件 -- 用戶id為: {{ id }} -- 姓名為:{{ uname }} -- 年齡為: {{ age }}</h1>' // 使用路由參數
]
})
命名路由
命名路由:給路由取別名
const router = new VueRouter({
routes: [
{
path: '/user/:id',
name: 'user',
component: User
}
]
})
<router-link :to="{ name: 'user',params: {id:123}}">User</router-link>
router.push({name:'user',params: {id:123}})
Example
var myRouter = new VueRouter({
//routes是路由規則數組
routes: [
//通過name屬性為路由添加一個別名
{ path: "/user/:id", component: User, name:"user"},
]
})
// 添加了別名之后,可以使用別名進行跳轉
<router-link to="/user">User</router-link>
<router-link :to="{ name:'user' , params: {id:123} }">User</router-link>
// 還可以編程式導航
myRouter.push( { name:'user' , params: {id:123} } )
Example1
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript" src="js/vue-router_3.0.2.js"></script>
</head>
<body>
<!-- 被 vm 實例所控制的區域 -->
<div id="app">
<router-link to="/user/1">User1</router-link>
<router-link to="/user/2">User2</router-link>
<router-link :to="{ name: 'user', params: {id: 3} }">User3</router-link>
<router-link to="/register">Register</router-link>
<!-- 路由占位符 -->
<router-view></router-view>
</div>
<script>
const User = {
props: ['id', 'uname', 'age'],
template: '<h1>User 組件 -- 用戶id為: {{id}} -- 姓名為:{{uname}} -- 年齡為:{{age}}</h1>'
}
const Register = {
template: '<h1>Register 組件</h1>'
}
// 創建路由實例對象
const router = new VueRouter({
// 所有的路由規則
routes: [
{path: '/', redirect: '/user'},
{
// 命名路由
name: 'user',
path: '/user/:id',
component: User,
props: route => ({uname: 'zs', age: 20, id: route.params.id})
},
{path: '/register', component: Register}
]
})
// 創建 vm 實例對象
const vm = new Vue({
// 指定控制的區域
el: '#app',
data: {},
// 掛載路由實例對象
// router: router
router
})
</script>
</body>
</html>
編程式導航
頁面導航的兩種方式
A.聲明式導航:通過點擊鏈接的方式實現的導航
B.編程式導航:調用js的api方法實現導航
Vue-Router常見導航方式
/*
Vue-Router中常見的導航方式:
this.$router.push("hash地址");
this.$router.push("/login");
this.$router.push({ name:'user' , params: {id:123} });
this.$router.push({ path:"/login" });
this.$router.push({ path:"/login",query:{username:"jack"} });
this.$router.go( n );//n為數字,參考history.go
this.$router.go( -1 );
*/
Example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript" src="js/vue-router_3.0.2.js"></script>
</head>
<body>
<!-- 被 vm 實例所控制的區域 -->
<div id="app">
<router-link to="/user/1">User1</router-link>
<router-link to="/user/2">User2</router-link>
<router-link :to="{ name: 'user', params: {id: 3} }">User3</router-link>
<router-link to="/register">Register</router-link>
<!-- 路由占位符 -->
<router-view></router-view>
</div>
<script>
const User = {
props: ['id', 'uname', 'age'],
template: `<div>
<h1>User 組件 -- 用戶id為: {{ id }} -- 姓名為: {{ uname }} -- 年齡為: {{ age }}</h1>
<button @click="goRegister">跳轉到注冊頁面</button>
</div>`,
methods: {
goRegister() {
this.$router.push('/register')
}
},
}
const Register = {
template: `<div>
<h1>Register 組件</h1>
<button @click="goBack">后退</button>
</div>`,
methods: {
goBack() {
this.$router.go(-1)
}
}
}
// 創建路由實例對象
const router = new VueRouter({
// 所有的路由規則
routes: [
{path: '/', redirect: '/user'},
{
// 命名路由
name: 'user',
path: '/user/:id',
component: User,
props: route => ({uname: 'zs', age: 20, id: route.params.id})
},
{path: '/register', component: Register}
]
})
// 創建 vm 實例對象
const vm = new Vue({
// 指定控制的區域
el: '#app',
data: {},
// 掛載路由實例對象
// router: router
router
})
</script>
</body>
</html>
Router.push()方法參數規則
/*
字符串(路徑名稱)
router.push('/home')
對象
router.push({path: '/home'})
命名的路由(傳遞參數)
router.push({name: '/user',params: {userId: 123}})
帶查詢參數,變成 /register?uname=lisi
router.push({ path: '/register', query: {uname: 'lisi' }})
*/
后台管理案例
點擊左側的"用戶管理","權限管理","商品管理","訂單管理","系統設置"都會出現對應的組件並展示內容
其中"用戶管理"組件展示的效果如上圖所示,在用戶管理區域中的詳情鏈接也是可以點擊的,點擊之后將會顯示用戶詳情信息。
案例思路
/*
1).先將素材文件夾中的11.基於vue-router的案例.html復制到我們自己的文件夾中。
看一下這個文件中的代碼編寫了一些什么內容,
這個頁面已經把后台管理頁面的基本布局實現了
2).在頁面中引入vue,vue-router
3).創建Vue實例對象,准備開始編寫代碼實現功能
4).希望是通過組件的形式展示頁面的主體內容,而不是寫死頁面結構,所以我們可以定義一個根組件:
*/
實現步驟
/*
1. 抽離並渲染App根組件
2. 將左側菜單改造為路由鏈接
3. 創建左側菜單對應的路由組件
4. 在右側主體區域添加路由占位符
5. 添加子路由規則
6. 通過路由重定向默認渲染用戶組件
7. 編程式導航跳轉到用戶詳情頁
8. 實現后退功能
*/
//只需要把原本頁面中的html代碼設置為組件中的模板內容即可
const app = {
template:`<div>
<!-- 頭部區域 -->
<header class="header">傳智后台管理系統</header>
<!-- 中間主體區域 -->
<div class="main">
<!-- 左側菜單欄 -->
<div class="content left">
<ul>
<li>用戶管理</li>
<li>權限管理</li>
<li>商品管理</li>
<li>訂單管理</li>
<li>系統設置</li>
</ul>
</div>
<!-- 右側內容區域 -->
<div class="content right">
<div class="main-content">添加用戶表單</div>
</div>
</div>
<!-- 尾部區域 -->
<footer class="footer">版權信息</footer>
</div>`
}
當我們訪問頁面的時候,默認需要展示剛剛創建的app根組件,我們可以
創建一個路由對象來完成這個事情,然后將路由掛載到Vue實例對象中即可
const myRouter = new VueRouter({
routes:[
{path:"/",component:app}
]
})
const vm = new Vue({
el:"#app",
data:{},
methods:{},
router:myRouter
})
補充:到此為止,基本的js代碼都處理完畢了,我們還需要設置一個路由占位符
<body>
<div id="app">
<router-view></router-view>
</div>
</body>
此時我們打開頁面應該就可以得到一個VueRouter路由出來的根組件了
我們需要在這個根組件中繼續路由實現其他的功能子組件
先讓我們更改根組件中的模板:更改左側li為子級路由鏈接,並在右側內容區域添加子級組件占位符
const app = {
template:`<div>
........
<div class="main">
<!-- 左側菜單欄 -->
<div class="content left">
<ul>
<!-- 注意:我們把所有li都修改為了路由鏈接 -->
<li><router-link to="/users">用戶管理</router-link></li>
<li><router-link to="/accesses">權限管理</router-link></li>
<li><router-link to="/goods">商品管理</router-link></li>
<li><router-link to="/orders">訂單管理</router-link></li>
<li><router-link to="/systems">系統設置</router-link></li>
</ul>
</div>
<!-- 右側內容區域 -->
<div class="content right">
<div class="main-content">
<!-- 在 -->
<router-view></router-view>
</div>
</div>
</div>
.......
</div>`
}
然后,我們要為子級路由創建並設置需要顯示的子級組件
//建議創建的組件首字母大寫,和其他內容區分
const Users = {template:`<div>
<h3>用戶管理</h3>
</div>`}
const Access = {template:`<div>
<h3>權限管理</h3>
</div>`}
const Goods = {template:`<div>
<h3>商品管理</h3>
</div>`}
const Orders = {template:`<div>
<h3>訂單管理</h3>
</div>`}
const Systems = {template:`<div>
<h3>系統管理</h3>
</div>`}
//添加子組件的路由規則
const myRouter = new VueRouter({
routes:[
{path:"/",component:app , children:[
{ path:"/users",component:Users },
{ path:"/accesses",component:Access },
{ path:"/goods",component:Goods },
{ path:"/orders",component:Orders },
{ path:"/systems",component:Systems },
]}
]
})
const vm = new Vue({
el:"#app",
data:{},
methods:{},
router:myRouter
})
展示用戶信息列表:
A.為Users組件添加私有數據,並在模板中循環展示私有數據
const Users = {
data(){
return {
userList:[
{id:1,name:"zs",age:18},
{id:2,name:"ls",age:19},
{id:3,name:"wang",age:20},
{id:4,name:"jack",age:21},
]
}
},
template:`<div>
<h3>用戶管理</h3>
<table>
<thead>
<tr>
<th>編號</th>
<th>姓名</th>
<th>年齡</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr :key="item.id" v-for="item in userList">
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.age}}</td>
<td><a href="javascript:;">詳情</a></td>
</tr>
</tbody>
</table>
</div>`}
```
當用戶列表展示完畢之后,我們可以點擊列表中的詳情來顯示用戶詳情信息,首先我們需要創建一個組件,用來展示詳情信息
const UserInfo = {
props:["id"],
template:`<div>
<h5>用戶詳情</h5>
<p>查看 {{id}} 號用戶信息</p>
<button @click="goBack">返回用戶詳情頁</button>
</div> `,
methods:{
goBack(){
//當用戶點擊按鈕,后退一頁
this.$router.go(-1);
}
}
}
然后我們需要設置這個組件的路由規則
const myRouter = new VueRouter({
routes:[
{path:"/",component:app , children:[
{ path:"/users",component:Users },
//添加一個/userinfo的路由規則
{ path:"/userinfo/:id",component:UserInfo,props:true},
{ path:"/accesses",component:Access },
{ path:"/goods",component:Goods },
{ path:"/orders",component:Orders },
{ path:"/systems",component:Systems },
]}
]
})
const vm = new Vue({
el:"#app",
data:{},
methods:{},
router:myRouter
})
再接着給用戶列表中的詳情a連接添加事件
const Users = {
data(){
return {
userList:[
{id:1,name:"zs",age:18},
{id:2,name:"ls",age:19},
{id:3,name:"wang",age:20},
{id:4,name:"jack",age:21},
]
}
},
template:`<div>
<h3>用戶管理</h3>
<table>
<thead>
<tr>
<th>編號</th>
<th>姓名</th>
<th>年齡</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr :key="item.id" v-for="item in userList">
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.age}}</td>
<td><a href="javascript:;" @click="goDetail(item.id)">詳情</a></td>
</tr>
</tbody>
</table>
</div>`,
methods:{
goDetail(id){
this.$router.push("/userinfo/"+id);
}
}
}
完整代碼
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>基於vue-router的案例</title>
<style type="text/css">
html,
body,
#app {
margin: 0;
padding: 0px;
height: 100%;
}
.header {
height: 50px;
background-color: #545c64;
line-height: 50px;
text-align: center;
font-size: 24px;
color: #fff;
}
.footer {
height: 40px;
line-height: 40px;
background-color: #888;
position: absolute;
bottom: 0;
width: 100%;
text-align: center;
color: #fff;
}
.main {
display: flex;
position: absolute;
top: 50px;
bottom: 40px;
width: 100%;
}
.content {
flex: 1;
text-align: center;
height: 100%;
}
.left {
flex: 0 0 20%;
background-color: #545c64;
}
.left a {
color: white;
text-decoration: none;
}
.right {
margin: 5px;
}
.btns {
width: 100%;
height: 35px;
line-height: 35px;
background-color: #f5f5f5;
text-align: left;
padding-left: 10px;
box-sizing: border-box;
}
button {
height: 30px;
background-color: #ecf5ff;
border: 1px solid lightskyblue;
font-size: 12px;
padding: 0 20px;
}
.main-content {
margin-top: 10px;
}
ul {
margin: 0;
padding: 0;
list-style: none;
}
ul li {
height: 45px;
line-height: 45px;
background-color: #a0a0a0;
color: #fff;
cursor: pointer;
border-bottom: 1px solid #fff;
}
table {
width: 100%;
border-collapse: collapse;
}
td,
th {
border: 1px solid #eee;
line-height: 35px;
font-size: 12px;
}
th {
background-color: #ddd;
}
</style>
<script src="js/vue_2.5.22.js"></script>
<script src="js/vue-router_3.0.2.js"></script>
</head>
<body>
<!-- 要被vue實例所控制的區域 -->
<div id="app">
<!-- 路由占位符 -->
<router-view></router-view>
</div>
<script>
// 定義APP根組件
const App = {
template: `
<div>
<header class="header">后台管理系統</header>
<div class="main">
<div class="content left">
<ul>
<li><router-link to="/users">用戶管理</router-link></li>
<li><router-link to="/rights">權限管理</router-link></li>
<li><router-link to="/goods">商品管理</router-link></li>
<li><router-link to="/orders">訂單管理</router-link></li>
<li><router-link to="/settings">系統設置</router-link></li>
</ul>
</div>
<div class="content right"><div class="main-content">
<router-view />
</div></div>
</div>
<footer class="footer">版權信息</footer>
</div>
`
}
const Users = {
data() {
return {
userlist: [
{id:1,name:'youmen1',age:10},
{id:2,name:'youmen2',age:20},
{id:3,name:'youmen3',age:30},
{id:4,name:'youmen4',age:40}
]
}
},
methods: {
goDetail(id){
console.log(id)
this.$router.push('/userinfo/' + id)
}
},
template: `<div>
<h3>用戶管理區域</h3>
<table>
<thead>
<tr><th>編號</th><th>姓名</th><th>年齡</th><th>操作</th></tr>
</thead>
<tbody>
<tr v-for="item in userlist" :key="item.id">
<td>{{ item.id }}</td>
<td>{{ item.name }}</td>
<td>{{ item.age }}</td>
<td>
<a href="javascript:;" @click="goDetail(item.id)">詳情</a>
</td>
</tr>
</tbody>
</table>
</div>`}
const UserInfo = {
props: ['id'],
template: `<div>
<h5>用戶詳情頁 --- 用戶Id為:{{id}}</h5>
<button @click="goback()">后退</button>
</div>`,
methods: {
goback() {
// 實現后退功能
this.$router.go(-1)
}
}
}
const Rights = { template: `<div>
<h3>權限管理區域</h3>
</div>`}
const Goods = { template: `<div>
<h3>商品管理區域</h3>
</div>`}
const Orders = { template: `<div>
<h3>訂單管理區域</h3>
</div>`}
const Settings = { template: `<div>
<h3>系統設置區域</h3>
</div>`}
// 創建路由對象
const router = new VueRouter({
routes: [
{
path: '/',
component: App,
redirect: '/users',
children: [
{ path: '/users', component: Users },
{ path: '/userinfo/:id', component: UserInfo, props: true },
{ path: '/rights', component: Rights },
{ path: '/goods', component: Goods },
{ path: '/orders', component: Orders },
{ path: '/settings', component: Settings }
]
}
]
})
const vm = new Vue({
el: '#app',
router
})
</script>
</body>
</html>