Vue学习笔记——路由
1. 路由基本概念
1. 后端路由
- 根据不同的用户 URL 请求,返回不同的内容
- url 请求地址 与 服务器资源之间 的对应关系
SPA
2. 前端路由
- 根据不同的用户事件,显示不同的页面内容
- 用户事件 与 事件处理函数 之间的对应关系
前端出现spa单应用程序
3. SPA
后端渲染(存在性能问题)=》Ajax前端渲染(前端渲染提高性能,但是不支持浏览器的前后退操作)=》
- SPA 单页面应用程序:整个网站只有一个页面,内容的变化通过Ajax局部更新实现、同时支持浏览器地址栏的前进和后退操作
- SPA实现原理之一:基于url地址的hash(hash的变化会导致浏览器记录访问历史的变化、但是hash的变化不会发出新的URL请求)
- 在实现SPA过程中,最核心的技术点就是前端路由
如何监听到hash值的变化?
监听 window 的 onhashchange事件
实现简单前端路由:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<!-- 导入 vue 文件 -->
<script src="./lib/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 :is="comName"></component>
</div>
<script type="text/javascript">
var zhuye ={
template:'<h1>zhuye</h1>',
}
var keji ={
template:'<h1>科技</h1>',
}
var caijing ={
template:'<h1>caijing</h1>',
}
var yule ={
template:'<h1>yule</h1>',
}
var vm = new Vue({
el:'#app',
data:{
comName:'zhuye',
},
components:{
'zhuye':zhuye,
'keji':keji,
'caijing':caijing,
'yule':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>
2. vue-router的基本使用
2.1 基本使用步骤:
- 引入相关的库文件
(导入 vue-router 文件,为全局 window 对象 挂载 VueRouter 构造函数) - 添加路由链接
<!-- router-link 是 vue 中提供的标签,默认会被渲染为 a 标签-->
<!-- to属性 默认会被渲染为href 属性-->
<!-- to属性的默认值 默认会被渲染为 # 开头的 hash 地址-->
<router-link to="/user">User</router-link>
- 添加路由填充位
< router-view>< /router-view>
- 定义路由组件
- 配置路由规则并创建路由实例
//创建路由实例
const router = new VueRouter({
//所有的路由规则
routes:[
{path:'/User',component:User},
{path:'/register',component:Register},
]
})
routes是路由规则组数
每个路由规则都是一个配置对象,其中至少包含 path 和 component 两个属性:
path 表示当前路由规则匹配的 hash 地址
component 表示当前路由规则对应要展示的组件
路由实例的路由规则中:
Component 只接受组件对象不接字符串
- 把路由挂载到Vue根实例中
//创建 vm 实例对象
const vm = new Vue({
el:'#app',
//挂载
//在es6中,如果属性名和属性值的变量名字是一致的,可以简写成为一个
router:router,
data:{}
})
2.2 路由重定向
路由重定向: 用户在访问地址A的时候,强制用户跳转到地址C,从而展示特定的组件页面
- 通过路由规则的 redirect 属性,指定一个新的路由地址
{ path: ’ / ', redirect: ’ /user ’ }
path:表示需要被重定向的原地址
redirect:表示将要被重定向的新地址
2.3 路由嵌套
确定谁是父组件、谁是子组件
然后在父组件中把要填写的路由链接、路由占位符都填充完毕
填充完之后发现还需要对应的子路由组件,所以创建两个路由组件
现在有组件、有对应链接,但是链接和组件对应关系暂时还没有,所以在routes路由规则中,在父组件路由规则之下,通过children子路由规则创建子路由的
子路由规则:children数组
// children 数组表示子路由规则
{ path: '/register', component: Register, children: [
{ path: '/register/tab1', component: Tab1 },
{ path: '/register/tab2', component: Tab2 }
] }
2.4 动态路由匹配
应用场景:通过动态路由参数的模式进行路由匹配
1. 基本用法
- 路由规则中,使用一个参数来接收就可以
{ path:’ /user/: id ',component:User }
- 组件中通过 $route.params获取路由参数
template:’< h1>User 组件 用户id为: {{$route.params.id}}< /h1>’
2. 路由组件传递参数
- props的值为布尔类型
{path:'/User/:id',component:User,props:true},
- props的值为对象类型
{path:'/User/:id',component:User,props:{uname:'xingxing',age:12}},
当props指定对象后,对象里面有什么样的属性,那么在组件中才可以接收到,
而 /user/:id的这个id就不能访问到了
- props的值为函数类型
//定义路由组件
const User = {
props:['id','uname','age'],
template:'<h1>User 组件 用户id为--- {{id}}---姓名:{{uname}}---年龄:{{age}}</h1>'
}
//创建路由实例
const router = new VueRouter({
//所有的路由规则
routes:[
{path:'/',redirect:'/User'},
{path:'/User/:id',component:User,props:route=>({uname:'zz',age:24,id:route.params.id})},
{path:'/register',component:Register,children:[
{path:'/register/tab1',component:Tab1},
{path:'/register/tab2',component:Tab2}
]},
]
})
2.5 命名路由
为了更加方便的表示路由的路径,可以给路由规则起一个别名,即为“命名路由”
const router = new VueRouter({
routes:[
{
path:'/user/:id',
name:'user',
component:User
}
]
})
那如何使用呢?
需要属性绑定 to,根据名字跳转到对应路由,params传递参数
<router-link :to="{ name:'user', params:{id:3}}">User</router-link>
2.7 编程式导航
1. 页面导航的两种方式
- 声明式导航:通过点击链接实现导航的方式
例如:普通网页中的< a>链接 或 vue 中的 < router-link> < /router-link> - 编程式导航:通过调用JavaScript形式的API实现导航的方式
例如:普通网页中的location.href
2. vue 中编程式导航基本用法
常用的编程式导航API如下:
- this.$router.push( ‘hash地址’)
router.push( )方法的参数规则
// 字符串(路径名称)
router.push( ‘/home’ )
// 对象
router.push({ path: ’ /home ‘})
//命名的路由(参数传递)
router.push({ name: ‘/user’ , params: {userId:1})
// 带查询参数,变成 /register?uname=lisi
router.push({ path:’ /register ', query: { uname: ’ lisi '}})
- this.$router.go(n) —实现前进和后退
const User = {
props:['id','uname','age'],
template:`<div>
<h1>User 组件 用户id为--- {{id}}---姓名:{{uname}}---年龄:{{age}}</h1>
<button @click="goRegister">跳转到register页面</button>
</div>`,
methods:{
goRegister:function(){
this.$router.push('/register');
}
}
}
const Register = {
template:`<div>
<h1>Register 组件</h1>
<button @click="goBack">后退</button>
<hr/>
<!--子路由链接-->
<router-link to="/register/tab1">Tab1</router-link>
<router-link to="/register/tab2">Tab2</router-link>
<!--子路由填充位-->
<router-view/>
</div>
`,
methods:{
goBack:function(){
this.$router.go(-1);
}
}
}