背景: vue是构建单页面应用,为了便于切换不同页面功能,因此引入了路由的概念,vue-router是路由管理器。前端路由的核心:改变试图不会向后端发送请求,而是切换对应的组件。
1、vueRouter(路由管理器)
路由开发优点:整体不刷新页面,用户体验好;数据传递容易,开发效率高
路由开发缺点:开发成本高、首页加载慢,不利于seo
使用: 使用Vue.use( )将VueRouter插入------------创建路由规则---------创建路由对象------将路由对象挂到 Vue 实例上---------设置路由挂载点
路由配置参数:
- path : 跳转路径
- component : 路径相对于的组件
- name:命名路由
- children:子路由的配置参数(路由嵌套)
- props:路由解耦
- redirect : 重定向路由
2、路由模式(vue默认使用hash)
- hash: 浏览器地址栏中会有 #,改变地址不会给服务器重新发送请求。原理是浏览器的hashchange,地址变化时,通过window.location.hash 获取地址上的hash值。
- history: 初次访问和刷新都会发请求(前进、后退不发请求),若请求不到会报404,所以需要在服务器端配置访问不到资源返回index.html页面。原理是根据html5的history接口,所以只兼容支持html5 history的浏览器
原理:基于HTML5新增的pushState()和replaceState()两个api,以及浏览器的popstate事件,地址变化时,通过window.location.pathname找到对应的组件 - abstract: 用得少,node.js服务器端
配置404页面
const router = new VueRouter({
routes: [
{ path: '*', redirect: {path: '/404'} } // 找不到的页面统一重定向到404
// 重定向写法还有(2)redirect:'/404'
// (3)redirect:{name:'404'}
// (4)redirect:to=>{ return '/404'}
]
})
3、router-link和router-view组件
router-link:跳转到指定路径的页面,等价于router.push或者是a标签
<router-link to="/setting">设置</router-link>
<!-- 属性如下
to:要去的路径 to:'/XX' ,也可放参数params和query---path的时候params不生效
tag:渲染成的组件,默认渲染成a标签 tag='li'
repalce:不会留下history,等价于调用router.replace
active-class:修改类型样式,渲染成a标签<a href='/home' class='router-link-exact-active router-link-active'>,若加上了 active-class='myclass',渲染后的class='router-link-exact-active myclass' ,此值也可在router全局配置中设置linkActiveClass
-->
router-view:渲染路由对应的组件
<router-view />
4、路由跳转
// 方式一:
<router-link to="/home">首页</router-link>
// 方式二:history会添加记录,回退退回上一页面
this.$router.push({ path: '/home' })
// 方式三:history不添加记录,回退退回上上页面
this.$router.replace({ path: '/home' })
// 方式四:向前向后跳转n个页面,n可为负数
this.$router.go(n)
// 其他
this.$router.back() // 后退
this.$router.forward() // 前进
5、路由传参
meta: 路由元信息,在routes配置中配置
// 放参数
{
path: '/home',
//.....其他属性
meta: { title: '首页' },
}
// 取参数
this.$route.meta.title
query: 普通路径 /path?id=‘’
// 1、放参数,有两种方式
this.$route.push({ path:'/home', query:{ name:'张三'}}) // 方式一
<router-link :to="{path:'/home',query:{ name:'张三'}}">首页</router-link> // 方式二
// 2、取参数
this.$route.query.name
params: :动态路由传参 /path/:id
// 1、前提====路由配置
{
path: '/home/:name',
//.....其他属性
}
// 2、放参数,有两种方式
this.$route.push({ name:'home', params:{ name:'张三'}}) // 方式一
<router-link :to="{name:'home',params:{ name:'张三'}}">首页</router-link> // 方式二
// 注意:params传参只能用name访问,用path不生效
// 3、取参数
this.$route.params.name
总结,params和query的区别
1、params需要用name引入,query既可以用name也可以用path
2、params 不会在地址栏展示参数,query以?方式拼接
3、params设置了路由后,不传参数会导致页面跳转报错,query无论是否有参数都会显示页面
4、params不设置路由时,刷新页面会丢失参数
6、路由守卫
(1)全局的路由守卫
// 路由跳转前,判断token、判断白名单什么的可在此方法中编写
router.beforeEach(async (to, from, next) => {
/* to 目标路由对象
from 当前路由对象
next 函数,必须调用 next()跳转 next(false)中断跳转 next({path:'/XX'})跳转其他路径
*/
})
// 解析守卫,在beforeRouteEnter后执行
router.beforeResolve((to,from) => {})
// 路由跳转后
router.afterEach((to,from) => {
window.scrollTo(0,0) // 滚动条回到顶部
})
(2)单个路由的路由守卫
// 注册路由时添加beforeEnter
{
path: '/home',
name: 'home',
component: Home,
beforeEnter(to, from, next) {
// TODO
}
}
(3)组件内的路由守卫
// 进入组件前,不能调用this,可通过next(vm=>{vm来调用实例})
beforeRouteEnter(to, from, next) {
// TODO
},
// 路由改变,但组件被复用时,比如list/1,list/2之间的跳转,this可用
beforeRouteUpdate(to, from, next) {
// TODO
},
beforeRouteLeave(to, from ,next) { // 离开路由前,通常用于保存数据,this可用
// TODO
}
完整的路由守卫
- 触发导航
- 失活的组件调用beforeRouteLeave
- 全局的beforeEach守卫
- 重用组件的beforeRouteUpdate
- 单个组件的beforeEnter
- 解析组件
- 激活组件调用beforeRouteEnter
- 全局解析守卫beforeResolve
- 全局的afterEach守卫
- 触发DOM更新
- 执行beforeRouteEnter 中next的回调函数
7、router和route的区别
$router 对象:全局路由实例,有push()、go()、replace()等方法
$route对象:当前页面路由实例,包含url参数、query\params对象、meta、path等信息
8、嵌套路由
- 列表页面进入编辑、新增、修改页面
- 菜单、头部一致,只是部分内容不一致
- tab切换的页面
9、路由缓存
切换路由,缓存页面数据(比如编辑页面编辑的数据),可使用keep-alive标签
10、动态加载路由
router.addRoutes(routes)
具体请看链接: vue-router ------用addRoutes 实现动态权限路由加载
11、Vue-router跳转和location.href有什么区别
location.href会刷新页面,history.pushState( /url )不会刷新,router.push( /url ),按需加载,减少dom消耗,vue-router就是用了 history.pushState() ,尤其是在history模式下。