vue-router
vue-router是vue的一个插件库,专门用来实现SPA单页面应用
对路由的理解
1.什么是路由
-
一个路由就是一组映射关系(key-value)
-
key是路径,value可以是 function 或 components
2.路由的分类
-
后端路由
-
理解:value是 function,用于处理客户端提交的请求
-
工作过程:服务器接收到一个请求时,根据请求路径找到匹配的函数来处理请求,返回响应的数据
-
-
前端路由
-
理解:value 是 component,用于展示页面内容
-
工作过程:当浏览器路径发生变化时,对应的组件就会显示
-
路由的基本使用
-
安装路由 npm i vue-router
-
在main.js 中应用 VueRouter Vue.use(VueRouter),并且在vue实例中配置 router(第三步创建)
import Vue from "vue"; import App from './App' import VueRouter from "vue-router"; import router from "./router/index" Vue.use(VueRouter) new Vue({ el:"#app", render:h => h(App), router:router, beforeCreate(){ Vue.prototype.$bus = this } })
-
创建router
//引入vue-router import VueRouter from "vue-router"; //引入组件 import Home from "@/components/Home.vue"; import About from "@/components/About.vue"; //创建router实例对象,管理路由规则 export default new VueRouter({ routes:[ { path:'/home', component:Home }, { path:'/about', component:About } ] })
routes 里面配置的一对对的路由规则,这里path 代表地址,component代表要跳转的组件
-
在模板中,用 <router-link active-class="active" to="/about">About</router-link>
来控制导航栏点击跳转,router-link 标签会自动解析成 a 标签,其中 active-class可以配置高亮效果,to属性表示跳转的地址
-
在模板中要放入 组件的位置用 <router-view></router-view> 来告诉router 组件放入的位置
<div class="row"> <div class="col-xs-2 col-xs-offset-2"> <div class="list-group"> <router-link class="list-group-item" active-class="active" to="/about">About</router-link> <router-link class="list-group-item" active-class="active" to="/home">Home</router-link> </div> </div> <div class="col-xs-6"> <div class="panel"> <div class="panel-body"> <router-view></router-view> </div> </div> </div> </div>
注意点:
-
路由组件一般放在pages文件夹中,一般组件一般放在 components文件夹下
-
通过切换,隐藏了的路由组件,默认是被销毁了,需要的时候再去挂载
-
每个组件都有自己的 $route 信息,里面存放自己的信息
-
整个应用只有一个 router,可以通过组件的 $router 获取
多级路由
在创建路由时,要配置多级路由 ,使用 children配置项,它是一个数组,数组里面是一个个子路由
routes:[
{
path:'/home',
component:Home,
children:[
{
path:'news',
component:News
},
{
path:'message',
component:Message
}
]
},
{
path:'/about',
component:About
}
]
需要注意的是,在子路由中path 前面一定不要再加 /,因为路由被解析时,会自动加 /
在跳转的地方 to属性中 要带上父路由的path
<li>
<router-link class="list-group-item" active-class="active" to="/home/news">News</router-link>
</li>
<li>
<router-link class="list-group-item" active-class="active" to="/home/message">Message</router-link>
</li>
路由的query参数
-
传递参数
在router-link 标签中的 to属性里面 的路径后携带参数,和路径用?隔开
<router-link to="/home/message/detail?id=001"></router-link>
如果想要用v-bind绑定to属性,可以用模板字符串来包裹路径和参数,这时参数要用${} 引入
<router-link :to="`/home/message/detail?id=${m.id}`"></router-link>
多个参数用 & 连接
上面是to的字符串写法,还可以将to写成对象
<router-link :to="{ path:'/home/message/detail', query:{ id:m.id, title:m.title } }"> </router-link>
-
接收参数
在需要接收参数的地方,使用 $route.query.id 来接收参数
命名路由
如果有多级路由,在跳转的地方,path会太长,如:/home/message/detail
这时可以使用 命名路由,也就是给路由起个名字,在定义路由的时候,配置name属性
这时 path就可以直接写name的值
需要注意的是 name只能在 to的对象写法中使用
路由的params参数
-
在配置路由时,需要声明接收params参数
routes:[ { path:'/home', component:Home, children:[ { path:'news', component:News }, { name:'xiaoxi' path:'message/:id/:title', component:Message } ] }, { path:'/about', component:About } ]
在path 中 用 :id 来占位
-
传递参数
在 router-link 标签中 to属性的两种写法
<!--第二种写法--> <router-link :to="`/home/message/${m.id}/${m.title}`"></router-link> <!--第二种写法--> <router-link :to="{ name:'xiaoxi', params:{ id:m.id, title:m.title } }"> </router-link>
注意,如果用to的对象写法,只能用name,不能用path
-
接收参数
$route.params.id 接收参数
路由中的 props 配置
作用:让路由组件更方便接收到参数
在router 的配置文件中,谁接收参数,就在谁里面配置props
props 有三种写法
children:[
{
// path:'details',
name:'detailsName',
path:'details/:id/:name',
component:Details,
// props的第一种写法,值为对象,,该对象中的所有key-value都会以props的形式传给Details组件,但值只能是死数据
//props:{id:'00000',name:'namename'}
//props 的第二种写法,值为布尔值,若为真,就会把该路由组件收到的所有params参数以props的形式传递给Details组件
// props:true
//props的第三种写法,值为函数,参数是 $route
props($route){
return{
id:$route.params.id,
name:$route.params.name
}
}
}
]
第三种写法要注意 拿到$route后,可以 用 $route.params 也可以用 $route.query,这取决于你上面用什么传递的参数
在第三种写法中,可以用 解构赋值 来简化代码。如下
props({params:{id,name}}){
return{id,name}
}
router-link的 replace属性
-
作用:控制路由跳转时操作浏览器历史记录的模式
-
浏览器的历史纪录有两种写入方式:分别为push 和 replace,push是追加历史记录,replace是替换当前记录,路由跳转默认是 push
-
如何开启replace模式,<router-link replace....></router-link>
编程式路由导航
在 $router 身上有很多方法可以实现路由的跳转,可以不借助 router-link
-
this.$router.push({该对象就是to里面的对象})
通过push 进行跳转
-
this.$router.replace({该对象就是to里面的对象})
通过replace进行跳转
-
this.$router.forward() 前进
-
this.$router.back() 后退
-
this.$router.go(数字) 前进或后退几步
缓存路由组件
之前我们离开一个组件,这个组件就会被销毁,如果我们不想让他销毁,就可以借助 keep-alive 标签,把router-view标签写在里面
<keep-alive include="News">
<router-view></router-view>
</keep-alive>
还可以通过 include 属性指定哪个组件不去销毁,如果不指定就都会销毁,这里指定的是组件名
缓存多个路由组件
<keep-alive :include="['News','Message']">
<router-view></router-view>
</keep-alive>
路由独有的生命周期钩子
作用:用于捕获路由组件的激活状态
-
activated:路由组件被激活时触发
-
deactivated:路由组件失活时触发
deactivated() {
clearInterval(this.timer)
},
activated() {
this.timer = setInterval(() =>{
this.opacity -= 0.01
if (this.opacity <= 0) this.opacity = 1
},16)
}
可以在deactivated 中关闭定时器等操作
路由守卫
路由守卫的作用是对路由进行权限控制
全局前置路由守卫
VueRouter的方法 beforeEach
每次路由切换之前被调用,初始化的时候会调用
在这个方法里面可以进行一些判断,来控制路由是否跳转
beforeEach 接收三个参数
-
to 要跳转到哪里去
-
from 从哪里跳转
-
next 放行,继续向下跳转
vueRouter.beforeEach((to,from,next) =>{
if (to.path === '/home/news' || to.path === '/home/message'){
if (localStorage.getItem('school') === 'sdgsxy2'){
next()
}else{
alert("没有权限")
}
}else{
next()
}
})
也可以用 路由的name属性去判断
在判断路径时,代码太长,可以使用 meta配置项,在meta中放一个布尔值,如果是true就进行权限验证,否则就不走
meta在想要进行权限判断的路由中加
{
path:'news',
component:News,
meta:{isAuth:true}
},
{
path:'message',
component:Message,
children:[
{
path:'details',
component:Details
}
],
meta:{isAuth:true}
}
vueRouter.beforeEach((to,from,next) => {
if (to.meta.isAuth){
if (localStorage.getItem('school') === 'sdgsxy2'){
next()
}else{
alert("没有权限")
}
}else{
next()
}
})
使用的时候 用 to.meta.isAuth 即可
全局后置路由守卫
afterEach 在初始化时执行,在每次路由切换之后执行
使用和前置路由守卫相同,没有 next参数,可以做一些只有路由跳转过来之后才能执行的操作
独享路由守卫
在某个路由里面配置路由守卫,只能该路由使用,配置项是 beforeEnter
{
path:'news',
component:News,
meta:{isAuth:true},
beforeEnter: (to,from,next) => {
if (to.meta.isAuth){
if (localStorage.getItem('school') === 'sdgsxy2'){
next()
}else{
alert("没有权限")
}
}else{
next()
}
}
},
组件路由守卫
-
beforeRouteEnter(to,from,next){} 通过路由规则,进入该组件时被调用
-
beforeRouteLeave(to,from,next){} 通过路由规则,离开该组件时被调用
路由器的两种工作模式
-
对于一个url来说,什么是hash值?
‘#’及其后面的内容就是 hash值
-
hash值不会包含在HTTP请求中,即hash值不会带给服务器
-
hash模式:
-
地址中永远带着 #
-
若以后将地址通过第三方手机app分享,若app校验严格,则地址会被标记为不合法
-
兼容性较好
-
-
history模式
-
地址美观
-
兼容性与hash相比略差
-
应用部署上线后需要后端人员支持,解决刷新页面服务端404的问题
-