一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第 19 天,点击查看活动详情。
路由守卫使用场景
今天先总结一下,开发中路由守卫使用场景
1、路由拦截部分页面如果没有登录或者登录了但没有权限,不允许访问。
beforeEach(to, from, next), 可以拦截所有导航
// 已配置好了所有路由,给需要守卫的路由添加标记,判断是否有权限访问路由
router.beforeEach((to, from, next) => {
// 路由是否需要守卫
if (to.meta.auth) {
// 是否登录
if (window.isLogin) {
// 如果登录了就放路由通行
next()
} else {
// 没有登录时,终止当前导航,跳转到新的页面(登录页面),同时设置了redirect:登录后应该显示的页面地址
next('/login?redirect='+to.fullPath)
}
} else {
// 无需守卫,即任何人都可以访问的页面,不需要控制页面权限的页面
next()
}
})
2、进入路由后,也就是路由被激活时,这时导航尚未结束,组件未渲染时,想要获取服务器数据
-
breforeRouterEnter(to, from, next)
breforeRouterEnter(to, from, next){ // 导航完成前,在路由进入的守卫中获取数据,在数据获取成功后执行导航 getData(to.params.id, post => { next(vm => { // 这里可以通过vm访问组件实例 }) }) }注意:这时组件实例还没被创建,不能直接通过this 访问数据,但next的回调方法来访问实例
3、beforeRouterUpdate(to, from, next)的实用场景
当beforeRouterUpdate钩子被执行时,代表组件被复用,这时导航未结束,组件已渲染,可以访问this
但路由变化但组件被复用时,声明周期钩子不会再重复调用
比如:使用动态路径参数或查询参数改变, 当参数改变beforeRouterUpdate会被调用, 这时如果想要根据参数获取服务器数据
beforeRouterUpdate(to, from, next) {
this.post = null
getData(to.params.id, post => {
this.setData(post) //操作返回数据
next()
})
}
4、上面说的都是在导航前执行的;对应如果导航后想要获取服务器数据呢?
- 使用组件内的生命周期钩子:created()
- 组件被复用,生命周期钩子不会再次调用
使用watch监听路由变化,获取数据。
动态添加路由
当需要控制路由权限时,上面提到了可以使用beforeEach拦截路由,使用beforeEach拦截时,首先所有路由都是已经配置;
那么如果说用户本来就没有访问某页面的权限,那能不能直接就不配置其路由?
可以通过router.addRoute添加一条新路由规则。如果该路由规则有 name,并且已经存在一个与之相同的名字,则会覆盖它。
router.beforeEach((to, from, next) =>{
// 要求:登录后才能访问页面,如果没有登录强制跳转登录页
if(window.isLogin){
if(to.path === '/login'){
next('/')
}else {
next()
}
}else {
if(to.path === '/login'){
next()
}else {
next('/login?redirect=' + to.fullPath)
}
}
})
登录后获取用户权限信息;动态添加某路由页面
login(){
window.isLogin = true;
this.$router.addRoute({
path: '/ceshi',
name: 'ceshi',
component: () => import('./RouterHook.vue')
});
const redirect = this.$route.query.redirect || "/";
this.$router.push(redirect);
}
路由组件缓存
利用keepalive做组件缓存,保留组件状态,提高执行效率
- include - 字符串或正则表达式。只有名称匹配的组件会被缓存。
- exclude - 字符串或正则表达式。任何名称匹配的组件都不会被缓存。
- max - 数字。最多可以缓存多少组件实例。一旦这个数字达到了,在新实例被创建之前,已缓存组件中最久没有被访问的实例会被销毁掉。
当组件在 内被切换,它的 activated 和 deactivated 这两个生命周期钩子函数将会被对应执行。
// about 是组件本身的名称
<keep-alive include="about">
<router-view></router-view>
</keep-alive>