- 学习目标:
- 路由的基本概念与原理
- Vue-router的基本使用
- 高级路由
- Vue-router嵌套路由
- Vue-router动态路由匹配(路由传参)
- Vue-router命名路由
- Vue-router编程式导航
- 基于vue-router的案例
【基本概念与原理】(P100~103)
路由是一个比较广义和抽象的概念,路由的本质就是对应关系。在开发中,路由分为:
1. 后端路由
- 概念:根据不同的用户 URL 请求,返回不同的内容
- 本质:URL 请求地址与服务器资源之间的对应关系
2. SPA(Single Page Application)
- 后端渲染(存在性能问题)
- Ajax前端渲染(前端渲染提高性能,但是不支持浏览器的前进后退操作)
- SPA(Single Page Application)单页面应用程序:整个网站只有一个页面,内
容的变化通过Ajax局部更新实现、同时支持浏览器地址栏的前进和后退操作
- SPA实现原理之一:基于URL地址的hash(hash的变化会导致浏览器记录访问历
史的变化、但是hash的变化不会触发新的URL请求)
- 在实现SPA过程中,最核心的技术点就是前端路由
3. 前端路由
- 概念:根据不同的用户事件,显示不同的页面内容
- 本质:用户事件与事件处理函数之间的对应关系
4. 实现简易前端路由
- 基于URL中的hash实现(点击菜单的时候改变URL的hash,根据hash的变化控制组件的切换)
1 2 3 4
| window.onhashchange = function() { }
|
模拟路由:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
| <!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> <script src="./lib/vue_2.5.22.js"></script> </head> <body> <div id="app"> <a href="#/zhuye">主页</a> <a href="#/keji">科技</a> <a href="#/caijing">财经</a> <a href="#/yule">娱乐</a>
<component :is="comName"></component> </div>
<script> const zhuye = { template: '<h1>主页信息</h1>' }
const keji = { template: '<h1>科技信息</h1>' }
const caijing = { template: '<h1>财经信息</h1>' }
const yule = { template: '<h1>娱乐信息</h1>' }
const vm = new Vue({ el: '#app', data: { comName: 'zhuye' }, components: { zhuye, keji, caijing, yule } })
window.onhashchange = function() { 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>
|
5. Vue Router
Vue Router( 官网:https://router.vuejs.org/zh/ )是 Vue.js 官方的路由管理器。
它和 Vue.js 的核心深度集成,可以非常方便的用于SPA应用程序的开发。
Vue Router 包含的功能有:
- 支持HTML5 历史模式或 hash 模式
- 支持嵌套路由
- 支持路由参数
- 支持编程式路由
- 支持命名路由
【Vue-router基本使用】(P104~105)
- 引入相关的库文件
- 添加路由链接
- 添加路由填充位
- 定义路由组件
- 配置路由规则并创建路由实例(重要!)
- 把路由挂载到 Vue 根实例中
1. 引入相关的库文件
1 2 3 4
| <script src="./lib/vue_2.5.22.js"></script>
<script src="./lib/vue-router_3.0.2.js"></script>
|
2. 添加路由链接
1 2 3 4 5
|
<router-link to="/user">User</router-link> <router-link to="/register">Register</router-link>
|
3. 添加路由填充位
1 2 3
| <router-view></router-view>
|
4. 定义路由组件
1 2 3 4 5 6
| var User = { template: '<div>User</div>' } var Register = { template: '<div>Register</div>' }
|
5. 配置路由规则并创建路由实例
1 2 3 4 5 6 7 8 9 10 11
| var router = new VueRouter({ routes: [ {path:'/user',component: User}, {path:'/register',component: Register} ] })
|
6. 把路由挂载到 Vue 根实例中
1 2 3 4 5
| new Vue({ el: '#app', router });
|
完整路由使用案例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| <!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> <script src="./lib/vue_2.5.22.js"></script> <script src="./lib/vue-router_3.0.2.js"></script> </head> <body> <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 } ] })
const vm = new Vue({ el: '#app', data: {}, router }) </script> </body> </html>
|
路由重定向
路由重定向指的是:用户在访问地址 A 的时候,强制用户跳转到地址 C ,从而展示特定的组件页面;
通过路由规则的 redirect 属性,指定一个新的路由地址,可以很方便地设置路由的重定向:
1 2 3 4 5 6 7 8
| var router = new VueRouter({ routes: [ {path:'/', redirect: '/user'}, {path:'/user',component: User}, {path:'/register',component: Register} ] })
|
【Vue-router嵌套路由】(P106)
1. 嵌套路由功能分析
通过路由的结构嵌套,在页面上展示出复杂的组件结构关系。
- 点击父级路由链接显示模板内容
- 模板内容中又有子级路由链接
- 点击子级路由链接显示子级模板内容
2. 父路由组件模板
1 2 3 4 5 6 7 8
| <p> <router-link to="/user">User</router-link> <router-link to="/register">Register</router-link> </p> <div> <router-view></router-view> </div>
|
3. 子级路由模板
1 2 3 4 5 6 7 8 9 10
| 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>` }
|
4. 嵌套路由配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| const router = new VueRouter({ routes: [ { path: '/user', component: User }, { path: '/register', component: Register, children: [ { path: '/register/tab1', component: Tab1 }, { path: '/register/tab2', component: Tab2 } ] } ] })
|
或者:
1 2 3 4 5 6 7 8 9 10 11 12 13
| const router = new VueRouter({ routes: [ { path: '/', redirect: '/user'}, { path: '/user', component: User }, { path: '/register', component: Register, children: [ { path: '/register/tab1', component: Tab1 }, { path: '/register/tab2', component: Tab2 } ] } ] })
|
完整嵌套路由使用案例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
| <!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> <script src="./lib/vue_2.5.22.js"></script> <script src="./lib/vue-router_3.0.2.js"></script> </head> <body> <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>
|
【Vue-router动态路由匹配】(P107)
1. 动态匹配路由的基本用法
思考:
1 2 3 4
| <router-link to="/user/1">User1</router-link> <router-link to="/user/2">User2</router-link> <router-link to="/user/3">User3</router-link>
|
1 2 3 4
| { path: '/user/1', component: User } { path: '/user/2', component: User } { path: '/user/3', component: User }
|
应用场景:通过动态路由参数的模式进行路由匹配
1 2 3 4 5 6
| var router = new VueRouter({ routes: [ { path: '/user/:id', component: User } ] })
|
1 2 3 4
| const User = { template: '<div>User {{ $route.params.id }}</div>' }
|
基本动态路由匹配案例1:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| <!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> <script src="./lib/vue_2.5.22.js"></script> <script src="./lib/vue-router_3.0.2.js"></script> </head> <body> <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: '<h1>Register 组件</h1>' }
const router = new VueRouter({ routes: [ { path: '/', redirect: '/user'}, { path: '/user/:id', component: User }, { path: '/register', component: Register } ] })
const vm = new Vue({ el: '#app', data: {}, router }) </script> </body> </html>
|
2. 路由组件传递参数
$route.params.id
与对应路由形成高度耦合,不够灵活,所以可以使用props将组件和路由解耦
(1) props的值为布尔类型
1 2 3 4 5 6 7 8 9 10 11 12
| const router = new VueRouter({ routes: [ { path: '/user/:id', component: User, props: true } ] }) const User = { props: ['id'], template: '<div>用户ID:{{ id }}</div>' }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| <!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> <script src="./lib/vue_2.5.22.js"></script> <script src="./lib/vue-router_3.0.2.js"></script> </head> <body> <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: '<h1>Register 组件</h1>' }
const router = new VueRouter({ routes: [ { path: '/', redirect: '/user'}, { path: '/user/:id', component: User, props: true }, { path: '/register', component: Register } ] })
const vm = new Vue({ el: '#app', data: {}, router }) </script> </body> </html>
|
(2) props的值为对象类型
1 2 3 4 5 6 7 8 9 10 11
| const router = new VueRouter({ routes: [ { path: '/user/:id', component: User, props: { uname: 'lisi', age: 12 }} ] }) const User = { props: ['uname', 'age'], template: '<div>用户信息:{{ uname + '---' + age}}</div>' }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| <!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> <script src="./lib/vue_2.5.22.js"></script> <script src="./lib/vue-router_3.0.2.js"></script> </head> <body> <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', 'uname', 'age'], template: '<h1>User 组件 -- 用户id为: {{id}} -- 姓名为:{{uname}} -- 年龄为:{{age}}</h1>' }
const Register = { template: '<h1>Register 组件</h1>' }
const router = new VueRouter({ routes: [ { path: '/', redirect: '/user'}, { path: '/user/:id', component: User, props: { uname: 'lisi', age: 20 } }, { path: '/register', component: Register } ] })
const vm = new Vue({ el: '#app', data: {}, router }) </script> </body> </html>
|
(3) props的值为函数类型
1 2 3 4 5 6 7 8 9 10 11 12
| const router = new VueRouter({ routes: [ { path: '/user/:id', component: User, props: route => ({ uname: 'zs', age: 20, id: route.params.id })} ] }) const User = { props: ['uname', 'age', 'id'], template: '<div>用户信息:{{ uname + '---' + age + '---' + id}}</div>' }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| <!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> <script src="./lib/vue_2.5.22.js"></script> <script src="./lib/vue-router_3.0.2.js"></script> </head> <body> <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', 'uname', 'age'], template: '<h1>User 组件 -- 用户id为: {{id}} -- 姓名为:{{uname}} -- 年龄为:{{age}}</h1>' }
const Register = { template: '<h1>Register 组件</h1>' }
const router = new VueRouter({ routes: [ { path: '/', redirect: '/user' }, { path: '/user/:id', component: User, props: route => ({ uname: 'zs', age: 20, id: route.params.id }) }, { path: '/register', component: Register } ] })
const vm = new Vue({ el: '#app', data: {}, router }) </script> </body> </html>
|
【Vue-router命名路由】(P109)
命名路由的配置规则
为了更加方便的表示路由的路径,可以给路由规则起一个别名,即为“命名路由”。
1 2 3 4 5 6 7 8 9
| const router = new VueRouter({ routes: [ { name: 'user', path: '/user/:id', component: User } ] })
|
1 2 3 4 5 6
| <router-link to="/user/3">User3</router-link>
<router-link :to="{ name: 'user', params: { id: 123 }}">User</router-link> router.push({ name: 'user', params: { id: 123 }})
|
命名路由完整案例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| <!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> <script src="./lib/vue_2.5.22.js"></script> <script src="./lib/vue-router_3.0.2.js"></script> </head> <body> <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 } ] })
const vm = new Vue({ el: '#app', data: {}, router }) </script> </body> </html>
|
【Vue-router编程式导航】(P110)
1. 页面导航的两种方式
2. 编程式导航基本用法
常用的编程式导航 API 如下:
this.$router.push('hash地址')
:跳转到指定路由页面
this.$router.go(n)
:后退
1 2 3 4 5 6 7 8 9
| const User = { template: '<div><button @click="goRegister">跳转到注册页面</button></div>', methods: { goRegister: function(){ this.$router.push('/register'); } } }
|
案例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
| <!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> <script src="./lib/vue_2.5.22.js"></script> <script src="./lib/vue-router_3.0.2.js"></script> </head> <body> <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 } ] })
const vm = new Vue({ el: '#app', data: {}, router }) </script> </body> </html>
|
3. 编程式导航参数规则
router.push() 方法的参数规则
1 2 3 4 5 6 7 8
| router.push('/home')
router.push({ path: '/home' })
router.push({ name: '/user', params: { userId: 123 }})
router.push({ path: '/register', query: { uname: 'lisi' }})
|
》基于vue-router的案例(P111~116)
》案例实现完整过程
1. 抽离并渲染 App 根组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
| <!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> </head> <body> <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> </body> </html>
|
1 2
| <script src="./lib/vue_2.5.22.js"></script> <script src="./lib/vue-router_3.0.2.js"></script>
|
1 2 3
| const vm = new Vue({ el: '#app' })
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| 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>` }
|
1 2 3 4 5 6 7
| const router = new VueRouter({ routes: [ { path: '/', component: App} ] })
|
1 2 3 4
| const vm = new Vue({ el: '#app', router })
|
1 2 3 4 5
| <div id="app"> <router-view></router-view> </div>
|
2. 将左侧菜单改造为路由链接
- 将左侧菜单改造为路由链接
- 改造前:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| 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>` }
|
- 改造后
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| 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="/right">权限管理</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">添加用户表单</div></div> </div> <!-- 尾部区域 --> <footer class="footer">版权信息</footer> </div>` }
|
3. 创建路由组件+右侧添加占位符
4. 添加子路由规则+路由重定向
5. 渲染用户列表数据
找到用户列表组件,定义date私有数据
- 插入数据前
1 2 3 4
| const Users = { template: `<div> <h3>用户管理区域</h3> </div>` }
|
- 插入数据后
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| const Users = { data() { return { userlist: [ { id: 1, name: '张三', age: 17 }, { id: 2, name: '李四', age: 18 }, { id: 3, name: '王五', age: 19 }, { id: 4, name: '赵六', age: 20 } ] } }, template: `<div> <h3>用户管理区域</h3> </div>` }
|
修改页面模板,并循环渲染出数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| const Users = { data() { return { userlist: [ { id: 1, name: '张三', age: 17 }, { id: 2, name: '李四', age: 18 }, { id: 3, name: '王五', age: 19 }, { id: 4, name: '赵六', age: 20 } ] } }, 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:;">详情</a></td> </tr> </tbody> </table> </div>` }
|
6. 编程式导航跳转+实现后退功能
》分析回顾
现在这个案例实现了,让我们回顾一下全部步骤:
- 抽离并渲染 App 根组件
- 将左侧菜单改造为路由链接
- 创建左侧菜单对应的右侧路由组件
- 在右侧主体区域添加路由占位符
- 添加子路由规则
- 通过路由重定向默认渲染用户组件
- 渲染用户列表数据
- 编程式导航跳转到用户详情页
- 实现后退功能
完整案例源码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238
| <!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="./lib/vue_2.5.22.js"></script> <script src="./lib/vue-router_3.0.2.js"></script> </head> <body> <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: '张三', age: 17 }, { id: 2, name: '李四', age: 18 }, { id: 3, name: '王五', age: 19 }, { id: 4, name: '赵六', age: 20 } ] } }, 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>
|
特别感谢:
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 百里飞洋! 技术内容: 若存在错误或不当之处,还望兄台不吝赐教,期待与您交流!