一、导航守卫
导航就是我们说的路由,当路由发生变化的时候,我们想要做的事情(如登录后才能进入的页面)
参数或查询的改变并不会触发进入/离开的导航守卫。
1、全局前置守卫router.beforeEach
使用 router.beforeEach
注册一个全局前置守卫,它在导航被触发后调用,按照创建顺序调用,此时导航在所有守卫 resolve 完之前一直处于等待中。
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => { ...})
参数:
①to:
要进入的路由对象 ②from:
从哪个路由离开
③next: Function:
next()
:如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。next的参数
next(
false
)
:
中断当前的导航,回到 from
路由对应的地址。
next(
'/'
)
或者 { path: '/' }:
跳转到一个不同的地址,还接收name等其他设置
next(
error)
:参数是一个Error实例,导航会被终止且该错误会被传递给 router.onError()
注册过的回调。
2、全局解析守卫 router.beforeResolve
区别是在导航被确认之前,所有组件内守卫和异步路由组件被解析之后被调用。
3、全局后置钩子:不接受 next
函数,也不改变导航本身
router.afterEach((to, from) => { ...})
4、路由独享的守卫
在路由配置上直接定义 beforeEnter
守卫:
5、组件内的守卫
可以在路由组件内直接定义以下路由导航守卫:(to,from,next)
①beforeRouteEnter:路由被confirm前调用,不能获取组件实例this。
但可以通过传一个回调给 next
,在导航被确认时执行。
②beforeRouteUpdate
:当前路由改变但该组件被复用时调用
③beforeRouteLeave:导航离开路由时调用
二、路由元信息
定义路由的时候可以配置 meta
字段。
一个路由匹配到的所有路由记录在 $route.matched
数组中,可以通过遍历 $route.matched
来检查路由记录中的 meta
字段。通过meta对象中的一些属性来判断当前路由是否需要进一步处理。
三、过渡动效
可以用 <transition>
组件给<router-view>
添加一些过渡效果:
<transition> <router-view></router-view> </transition>
1、单个路由过渡动效
想让每个路由组件有各自的过渡效果,可以在各路由组件内使用 <transition>
并设置不同的 name
2、基于路由的动态过渡
基于当前路由与目标路由的变化关系,动态设置过渡效果:
①使用动态的 transition name <transition :name="transitionName">
②在父组件内 watch $route 决定使用哪种过渡
watch: {
'$route' (to, from) {
const toDepth = to.path.split('/').length
const fromDepth = from.path.split('/').length
this.transitionName = toDepth < fromDepth ? 'slide-right' : 'slide-left' }}
四、数据获取
进入某个路由后,需要从服务器获取数据,可以通过两种方式来实现:
导航完成之后获取:先完成导航,在组件created中获取数据,在数据获取期间显示“加载中”之类的指示。
导航完成之前获取:导航完成前,在路由进入的守卫中beforRouterEnter获取数据,在数据获取成功后执行导航。
五、滚动行为
当切换到新路由时,想要页面滚到顶部,或者是保持原先的滚动位置。
当创建一个 Router 实例,你可以提供一个 scrollBehavior
方法:
scrollBehavior (to, from, savedPosition) {
return { x: number, y: number }
//或者return{ selector: string, offset? : { x: number, y: number }}
}
1、savedPosition
当且仅当 popstate
导航 (通过浏览器的 前进/后退 按钮触发) 时才可用。
2、return savePosition,在按下后退/前进 按钮时,就会像浏览器的原生表现那样。
3、模拟“滚动到锚点”的行为
scrollBehavior (to, from, savedPosition) {
if (to.hash) {
return { selector: to.hash } } }
4、异步滚动
令其滚动行为和页面过渡一起良好运行
scrollBehavior (to, from, savedPosition) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({ x: 0, y: 0 })
}, 500)
})
}
六、 路由懒加载
把不同路由对应的组件分割成不同的代码块,当路由被访问时才加载对应组件,提高页面加载效率。
1、将异步组件定义为返回一个 Promise 的工厂函数 ,使用动态import语法来定义代码分块点,能够被 Webpack 自动代码分割
const Foo = () => import('./Foo.vue')
2、把组件按组分块
想把某个路由下的所有组件都打包在同个异步块中:使用命名chunk,通过特殊的注释语法来提供 chunk name
const Foo = () => import(/* webpackChunkName: "group-foo" */ './Foo.vue')
const Bar = () => import(/* webpackChunkName: "group-foo" */ './Bar.vue')