一、路由的基本概念
路由的本质就是对应关系,在开发中,分为前端路由和后端路由。
1. 后端路由
概念:根据不同的用户 URL 请求,返回不同的内容
本质:URL 请求地址与服务器资源之间的对应关系
- 后端路由有性能问题,Ajax前端渲染提高性能,但是不支持浏览器的前进后退操作
- SPA(Single Page Application)单页面应用程序:整个网站只有一个页面,内容的变化通过Ajax局部更新实现、同时支持浏览器地址栏的前进和后退操作
- SPA实现原理之一:基于URL地址的hash(hash的变化会导致浏览器记录访问历史的变化、但是hash的变化不会触发新的URL请求)
- 在实现SPA过程中,最核心的技术点就是前端路由
2. 前端路由
概念:根据不同的用户事件,显示不同的页面内容
本质:用户事件与事件处理函数之间的对应关系
2.1 实现简易版前端路由
占位符是动态显示的部分
<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>
Vue
// 定义组件
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
}
})
// hash值改变就会触发
window.onhashchange = function() {
// location.hash 最新的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
}
}
显示:
二、Vue Router 路由管理器
官网:https://router.vuejs.org/zh/
- 支持HTML5 历史模式或 hash 模式
- 支持嵌套路由
- 支持路由参数
- 支持编程式路由
- 支持命名路由
1. 基本使用
- 引入相关的库文件
- 添加路由链接
- 添加路由占位符
- 定义路由组件
- 配置路由规则并创建路由实例
- 把路由挂载到 Vue 根实例中
<!-- 1.导入 vue 文件 -->
<script src="./lib/vue_2.5.22.js"></script>
<script src="./lib/vue-router_3.0.2.js"></script>
<div id="app">
<!-- 2.添加路由链接 -->
<router-link to="/user">User</router-link>
<router-link to="/register">Register</router-link>
<!-- 3.路由占位符 -->
<router-view></router-view>
</div>
<script>
// 4.定义路由组件
const User = {
template: '<h1>User 组件</h1>'
}
const Register = {
template: '<h1>Register 组件</h1>'
}
// 5.创建路由实例对象
const router = new VueRouter({
// 所有的路由规则
routes: [
{ path: '/user', component: User },
{ path: '/register', component: Register }
]
})
const vm = new Vue({
el: '#app',
data: {},
// 6.挂载路由实例对象
router // router: router简写
})
</script>
显示:
2. 路由重定向
路由重定向指的是:用户在访问地址 A 的时候,强制用户跳转到地址 C 。
通过路由规则的 redirect 属性,指定一个新的路由地址。
更改上个案例,只添加了一句
const router = new VueRouter({
routes: [
{ path: '/', redirect: '/user'}, // 指定一个新的路由地址
{ path: '/user', component: User },
{ path: '/register', component: Register }
]
})
显示:
3. 嵌套路由
<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 }
] }
]
})
const vm = new Vue({
el: '#app',
data: {},
router
})
</script>
显示:
4. 动态匹配路由
<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="./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>
显示:
更方便的使用请求参数id
如果 props 被设置为 true,route.params 将会被设置为组件属性
<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'], // 2.prop内定义id,就可以拿到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 }, // 1.开启props传参
{ path: '/register', component: Register }
]
})
const vm = new Vue({
el: '#app',
data: {},
router
})
</script>
显示:与上一个相同
使用更多参数
<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>
显示:
5. 路由命名
给路由命名后,链接更简单
<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>
显示:与上一个相同
6. 编程式导航
- 声明式导航:通过点击链接实现导航的方式,叫做声明式导航
例如:普通网页中的 <a></a> 链接 或 vue 中的 <router-link></router-link>
- 编程式导航:通过调用JavaScript形式的API实现导航的方式,叫做编程式导航
例如:普通网页中的 location.href
常用的编程式导航 API 如下:
- this.$router.push('hash地址') 跳转到指定页面
- this.$router.go(n) -1 后退一页 1 前进一页
<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>
显示: