vue路由
Vue-Router
vue的一个插件库,专门用来实现 SPA应用
对SPA应用的理解
- 单页web应用(single page web application, SPA)
- 整个应用只有一个完整的页面
- 单击页面中的导航链接不会刷新页面,只会做页面的局部更新
- 数据需要通过 ajax 请求获取
路由的理解
什么是路由
- 一个路由就是一组映射关系(key-value)
- key为路径,value可能是funciton 或 component
路由分类
- 后端路由
- 理解:value 是 function,用于处理客户端提交的请求
- 工作过程:服务器接收到一个请求时,根据请求路径找到匹配的函数来处理请求,返回响应数据
- 前端路由
- 理解:value是 component,用于展示页面内容
- 工作过程:当浏览器的路径改变时,对应的组件就会显示
路由的基本使用
一个路由(route)就是一组映射关系(key-value),多个路由需要路由器(router)进行管理
前端路由:key是路径,value是组件
- 安装vue-route,命令: npm i vue-router
- 应用插件: Vue.use(VueRouter)
- 编写router配置项
//引入VueRouter import VueRouter from 'vue-router' //引入路由组件 import About from '../components/About' import Home from '../components/Home' //创建router实例对象,去管理一组一组的路由规则 const router = new VueRouter({ routes:[ { path:'/about', components:About }, { path:'/home', components:Home } ] }) //暴露router export default router
- 实现切换(active-class可配置高亮样式)
<router-link active-class="active" to="/about">About</router-link>
- 指定展示位置
<router-view></router-view>
关于路由的注意点
- 路由组件通常存放在 pages 文件夹,一般组件通常放在 components 文件夹
- 通过切换,“隐藏”了的路由组件,默认是被销毁掉的,需要的时候再去挂载
- 每个组件都有自己的 $route 属性,里面存储着自己的路由信息
- 整个应用只有一个 router,可以通过组件的 $router 属性获取到
嵌套路由(多级路由)
- 配置路由规则,使用 children 配置项:
routes:{ path:'/about', component:About, }, { path:'/home', component:Home, //通过 children 配置子级路由 children:[ { // 此处 path 中,一定不要写 /news,不需要这个反斜杠 path:'news', component:News }, { // 此处 path 中,一定不要写 /message,不需要这个反斜杠 path:'message', component:Message } ] }
- 跳转
//此处 要去的路由 相当于一个绝对路径,从父级路由开始写 <router-link to="/home/news">News</router-link>
路由的query参数
- 传递参数
<!-- 跳转并携带 query 参数,to 的字符串写法 --> <router-link :to="/home/message/detail?id=666&title=hello">跳转</router-link> <!-- 跳转并携带 query 参数,to 的对象写法 --> <router-link :to="{ path:"/home/message/detail", query:{ id:666, title:'你好' } }" >跳转<router-link>
- 接收参数
$route.query.id $route.query.title
命名路由
- 作用:可以简化路由的跳转
- 如何使用
- 给路由命名
{ path:'demo', component:Demo, children:[ { path:'test', component:Test, children:[ { name:'hello', // 给路由命名 path;'welcome', component:Hello } ] } ] }
- 简化跳转
<!-- 简化前,需要写完整的路径 --> <router-link to="/demo/test/welcome">跳转</router-link> <!-- 简化后,直接通过名字跳转 --> <router-link :to="{name:'hello'}">跳转</router-link> <!-- 简化写法配合传递参数 --> <router-link :to="{ name:'hello', query:{ id:666, title:'你好' } } >跳转</router-link>
- 给路由命名
路由的params参数
- 配置路由,声明接收 params 参数
{ path:'/home' component:Home, children:[ { path:'news', component:News }, { path:'message', component:Message, children:[ { name:'detail', //使用占位符声明接收params 参数 path:'detail/:id/:title', component:Detail } ] } ] }
- 传递参数
<!-- 跳转并携带params参数,to的字符串写法 --> <router-link :to="/home/message/detail/666/你好">跳转</router-link> <!-- 跳转并携带params参数,to的对象写法 --> <router-link :to="{ name:"detail", params:{ id:666, title:"你好" } }" >跳转</router-link>
- 接收参数
$route.params.id $route.params.title
特别注意:路由携带 params 参数时,若使用 to 的对象写法,则不能使用 path 配置路由,必须使用 name 配置
路由的props配置
作用:让路由组件更方便的收到参数
name:'detail'
path:'detail/:id/:title'
component:Detail,
//第一种写法,props为对象,该对象中所有的key-value的组合最终都会通过props传给Detail组件
props:{id:666, title:"你好"}
// 第二种写法,props值为布尔值,则把路由收到的所有params参数通过props传递给detail组件
props:true
//第三种写法:props值为函数,该函数返回的对象中每一组 key-value都会通过props传给Detail组件
props(route) {
return {
id:route.query.id,
title:route.query.title
}
}
接收:在组件中使用 props[‘xxx’, ‘xxx’]接收
<router-link>的replace属性
- 作用:控制路由跳转时操作浏览器历史记录的模式
- 浏览器默认的历史记录有两种写入方式:分别为push 和 replace ,push是追加历史记录,replace 是替换当前记录,路由跳转时候默认为 push
- 如何开启 replace 模式:<router-link replace …>News</router-link>
编程式路由导航
- 作用:不借助 <router-link>实现路由跳转,让路由跳转更加灵活
- 具体编码
//$router的两个API this.$route.push({ name:'detail', params:{ id:xxx, title:xxx } }) this.$router.replace({ name:'detail', params:{ id:xxx, title:xxx } }) this.$route.forward() //前进几步 this.$route.back() //后退几步 this.$route.go() //前进或后退几步,参数为正数就是前进,负数就是后退
缓存路由组件
- 作用:因为隐藏的组件默认是被销毁的,再切换回来的时候再次挂载,所以缓存路由组件的作用就是让不展示的组件保持挂载,不被销毁
- 具体编码
<!-- 若没有include属性,则让当前层级下的所有子路由保持挂载 --> <!-- include指定让某个组件保持挂载其他组件不保持挂载 --> <keep-alive include="News"> <router-view></router-view> </keep-alive>
和路由有关的生命周期钩子
- 作用:路由组件所独有的两个钩子,用于捕获路由组件的激活状态
- 具体名字:
- activated 路由组件被激活时触发
- deactivated 路由组件失活时触发
路由守卫
作用:对路由进行权限控制
分类:全局守卫、独享守卫、组件守卫
全局守卫
// 全局前置守卫,初始化时执行、每次路由切换前执行
route.beforeEach((to, from, next)=>{
if() { //判断是否需要权限控制
if() { // 判断是否有权限
}
else{ // 无权限处理
}
}
else {
next()//放行
}
})
//全局后置守卫,初始化时执行、每次路由切换后执行
router.afterEach((to, from)=>{
})
独享守卫
// 在进入某个特定路由时触发,to 去哪个路由, from 从那个路由来
// next() 放行
beforeEnter(to, from, next) {
}
组件内守卫
//进入守卫,通过路由规则,进入该组件时被调用
beforeRouteEnter(to, from, next){}
//离开守卫,通过路由规则,离开该组件是被调用
beforeRouteLeave(to, from, next){}