vue-router
1 路由概述
vue-router是vue的一个插件,用来提供路由功能
。通过路由的改变
可以动态加载组件
,达到开发单页面程序的目的。
2 基本使用
1) 声明组件
let com1 = {template:`<div>this is com1</div>`}
let com2 = {template:`<div>this is com2</div>`}
let com3 = {template:`<div>this is com3</div>`}
2) 声明路由器
router是路由器对象,routes是路由列表
let router = new VueRouter({
routes: [
{
path: '/a', // 路由地址
component: com1,// 对应组件
name: 'comA', // 给路由设置名字,方便使用name进行跳转
redirect: '/c', // 重定向
alias: '/coma', // 别名
},
{ path: '/b', component: com2 },
{ path: '/c', component: com3 },
]
})
3)路由注册
在vue的根实例中,注册路由
let vm = new Vue({
el: '#app',
router //等价于router:router
})
4)路由使用
<router-link to="/a">A组件</router-link>
<router-link to="/b">B组件</router-link>
<router-link to="/c">C组件</router-link>
// 路由视口,用来加载路由对应的组件
<router-view></router-view>
3 动态路由
3.1 声明
let router = new VueRouter({
routes: [
// 动态路由参数以冒号开头
{ path: '/user/:username/:id', component:com1 }
]
})
<router-link to="/user/zhangsan/1001"></router-link>
3.2 路由参数
对于获取路由携带参数(参数值会被设置到 this.$route.params中)
/user/zhangsan/1001和/user/lisi/1002都将映射同一个组件,
在一个组件内部发生动态路由变化时,vue组件实例会被复用,而不会重新销毁再创建;
组件内部发生动态路由变化,想要监听路由参数变化时,可以使用watch监听$route,
或者使用组件内部的导航守卫。
let com1 = {
data() {
return {
id: null,
username: null
}
},
template: ``,
created() {
// 在created钩子函数中,只能一次性获取携带的参数,不能够持续获取
this.id = this.$route.params.id;
this.username = this.$route.params.username;
},
watch() {
// 使用watch监听器,可以持续监听路由器对象中,携带参数的变化
$route(to, from) {
this.id = to.params.id;
this.username = to.params.username;
}
}
}
4 路由守卫
4.1 介绍
正如其名,vue-router提供的导航守卫主要用来通过跳转或取消的方式守卫导航。
每个守卫方法接收三个参数:
to: Route 即将要进入的目标 路由对象
from: Route 当前导航正要离开的路由
next: Function 一定要调用该方法来 resolve 这个钩子,让路由跳转继续进行
next(): 进行管道中的下一个钩子(继续完成导航跳转)
next(false): 中断当前的导航。
next('/') 或者 next({ path: '/' }): 跳转到一个不同的地址。
守卫是异步解析执行,导航在所有守卫 resolve 完之前一直处于等待中。
4.2 全局守卫
let router = new VueRouter({
routes: [
{...}
]
})
1)全局前置守卫
router.beforeEach((to, from, next) => {
.......拦截操作
next();
})
2) 全局后置守卫
router.afterEach((to, from) => {
.......之后操作
})
3) 路由独享守卫
let router = new VueRouter({
routes: [
{
path: '/a',
component: com1,
beforeEnter(to, from, next) {
.......拦截操作
next();
}
}
]
})
4) 组件内守卫
let com1 = {
data(){
return {}
},
template: ``,
// 进入当前组件之前拦截
beforeRouteEnter(to, from, next) {
.......拦截操作
next();
},
// 在当前组件中,路由发生改变时触发
beforeRouteUpdate(to, from, next) {
.......拦截操作
next();
},
// 离开当前组件之前,触发
beforeRouteLeave(to, from, next) {
.......拦截操作
next();
}
}
5 嵌套路由
品字形布局:上面头部,左侧导航栏,右侧内容区域
嵌套路由的定义(children属性中定义子路由)
let router = new VueRouter({
routes: [
{
path: '/student',
component: comStu,
children: [
{ path: 'grade', component: comGrade },
{ path: 'register', component: comRegister },
]
}
]
})
使用
一级路由对应一个router-view
二级路由对应一个router-view
6 编程式导航
1)this.$router.push() // 在history历史栈中新增一条记录
this.$router.push({ path: '/a' })
this.$router.push({ name: 'comA' })
路由跳转并携带参数
· 路径path跳转和query搭配使用
this.$router.push({ path: '/a', query: { username: 'zhangsan' } })
· 名字name跳转和params搭配使用
this.$router.push({ name: 'comA', params: { age: 12 } })
参数获取
在跳转的目标组件中,只要能够访问到$route就能拿到跳转携带的参数
例如:在目标组件的created(){
console.log(this.$route.params)
console.log(this.$route.query)
}
query传参和params传参区别
1.query传参参数保存在url地址栏中,以查询字符串的形式拼接上去
2.安全性来讲,params比较安全,query会显示在地址栏中,容易造成数据泄露
3.刷新页面时,query中的数据不受影响,而params中的数据直接消失
2)this.$router.replace() // 直接替换当前路由,不会产生新的历史记录
3)this.$router.go() // 内部接受正值或负值的整数作为参数,正数就是前进,负数就是后退(在历史记录中)
具体案例:
<head>
<title>编程式导航</title>
<script src="../js/vue.js"></script>
<script src="../js/vue-router.js"></script>
<style>
header{
height: 50px;
background-color: blue;
}
main{
display: flex;
}
.left{
width: 150px;
border: 3px solid orange;
height: 650px;
margin: 10px 10px 0 0;
}
.right{
flex: 1; /* width: calc(100%-150px);相当于flex:1 */
border: 3px solid red;
height: 650px;
margin-top: 10px;
}
</style>
</head>
<body>
<div id="app">
<header>我是网站头部</header>
<main>
<div class="left">
<!-- 4.路由的使用 -->
<router-link to="/user">用户管理</router-link><br/>
<router-link to="/student">学生管理</router-link><br/>
<router-link to="/class">班级管理</router-link><br/>
</div>
<div class="right">
<!-- 实现了组件之间的动态加载 -->
<router-view></router-view>
</div>
</main>
</div>
<script>
// 1.注册组件
let com1={
data(){
return{}
},
template:`
<div>
用户管理
</div>
`
}
let com2={
data(){
return{}
},
template:`
<div>
学生管理<br/>
<div>
<button @click="clickHandler">成绩管理</button>
<button @click="clickHandler">学籍管理</button>
<button @click="$router.go(1)">返回</button>
</div>
<router-view></router-view>
</div>
`,
methods:{
clickHandler(e){
if(e.target.innerText == '成绩管理'){
// 使用this.$router.push 完成编程式导航
// this.$router.push({path:'/student/grade'})
// 判断当前自己是自己就不用跳转了
if(this.$route.fullPath !== '/student/grade'){
// this.$router.push({
// name:'grade',
// params:{
// id:1001,
// name:'zhansgan'
// }
// })
// 路由替换
this.$router.replace('/student/grade')
// go方法 后可以跟一个整数
}
}else{
// this.$router.push({path:'/student/register'})
if(this.$route.fullPath !== '/student/register'){
// 使用path跳转
this.$router.push({
name:'register',
query:{
id:1002,
name:'lisi'
}
})
}
}
}
}
}
let com3={
data(){
return{}
},
template:`
<div>
班级管理
</div>
`
}
// 2.定义路由
let comGrade={
data(){
return{}
},
template:`
<div>
成绩管理
</div>
`,
created(){
console.log('params',this.$route.params);
}
}
let comRegister={
data(){
return{}
},
template:`
<div>
学籍管理
</div>
`,
created(){
console.log('query',this.$route.query);
}
}
// 2.定义路由
let router = new VueRouter({
// 修改路由模式 默认模式是hash
mode:'history',
routes:[
{ path:'/user',component:com1 },
{
path:'/student',
component:com2,
children:[
{path:'grade',component:comGrade,name:'grade'},
{path:'register',component:comRegister,name:'register'},
]
},
{ path:'/class',component:com3 }
]
})
let vm = new Vue({
el:"#app",
data:{},
methods:{},
// 3.路由注册
router
})
</script>
</body>
</html>
7 路由模式
7.1 修改路由模式
vue-router 默认 hash 模式 —— 使用 URL 的 hash 来模拟一个完整的 URL,于是当 URL 改变时,页面不会重新加载。如果不想要很丑的 hash,可以用路由的 history 模式,这种模式充分利用 history.pushState API 来完成 URL 跳转而无须重新加载页面。不过要想使用这种模式,还需要后台配置支持。
let router = new VueRouter({
// mode: 'hash',
mode: 'history', // mode属性修改路由模式,默认为hash模式
routes: []
})
7.2 hash路由和history路由的区别:
1.hash路由在地址栏URL上有#
,而history路由没有#
,并且更精简;
2.进行回车刷新操作,hash路由会加载到地址栏对应的页面
,而history路由一般就404报错
了;(刷新是网络请求,history路由需要后端支持)。
3.hash路由支持低版本的浏览器
,而history路由是HTML5新增的API。
4.hash的特点在于它虽然出现在了URL中,但是不包括在http请求中
,所以对于后端是没有一点影响
的,所以改变hash不会重新加载页面
,所以这也是单页面应用的必备。
5.history运用了浏览器的历史记录栈,之前有back,forward,go方法,之后在HTML5中新增了pushState()和replaceState()方法(需要特定浏览器的支持),它们提供了对历史记录进行修改的功能,不过在进行修改时,虽然改变了当前的URL,但是浏览器不会马上向后端发送请求。