vue笔记8
10.路由守卫
路由的钩子函数称为路由守卫。分为全局守卫、路由独享守卫、组件内部生命周期守卫。
- 全局守卫:
- 全局前置钩子:router.beforeEach(to,from,next),------前端鉴权
- 全局解析钩子:router.beforeResolve(to,from,next)
- 全局后置钩子:router.afterEach(to,from)
- 路由独享的守卫
- beforeEnter(to,from,next)
- 组件内部的生命周期守卫
- beforeRouteLeave:从该组件离开
- beforeRouteEnter(to,from,next):组件被激活
- beforeRouteUpdate(to,from,next):组件被重用时调用
全局前置钩子:
-
router.beforeEach(fn),当路由发生更改时会调用这个钩子。一般用于前端鉴权:判断用户的登录状态,若未登录则跳转到登录页面。 -
参数:
- to:即将进入的路由对象
- from:当前要离开的路由对象
- next():只有当这个函数被调用时,这个钩子才会被resolved。
- next():执行管道中的下一个钩子,如果全部钩子执行完毕,则导航确认,页面跳转。
- next(false):中断当前的导航。如果浏览器的URL改变,页面会重置到from路由对应的页面。
- next("/")或者next({path:’/’}):重定向到指定的路由。
//配置全局前置守卫,在router.js文件中进行配置
import Vue from 'vue';
// 引入路由
import VueRouter from 'vue-router';
// 我们可以通过这种方式引入路由,在下面放到component属性上,也可以在下面通过异步组件导入
// import my from '@/views/my.vue'
// 启用路由
Vue.use(VueRouter);
let routers = [{
path: '/',
name: 'index',
component: () => import('@/views/index.vue')
},
{
path: '/login',
name: 'login',
component: () => import('@/views/login.vue')
},
{
path: '/my',
name: 'my',
component: () => import('@/views/my.vue')
}
]
let router = new VueRouter({
// 注意参数这个对象里面属性名必须是routes
routes: routers
});
router.beforeEach((to, from, next) => {
console.log(to, from, next);
if (to.path != '/login' && !sessionStorage.getItem('isLogin')) {
next('login')
} else {
next();
}
})
export default router;
全局解析钩子:
- router.beforeResolve(fn):导航被确认之前,所有组件内守卫和异步路由组件被解析之后,在失活的组件里调用router.beforeResolve()
全局后置钩子:
-
router.afterEach(to,from):没有next函数,当导航被确认之后被触发,不会改变导航本身。一般应用于在组件跳转后,让滚动条回到顶部。 router.afterEach((to, from) => {
console.log("afterEach")
//路由已经匹配了 开始组件替换router-views,组件进入
//操作window
window.scrollTo(0, 0)
})
路由独享守卫:
-
beforeEnter(to,from,next):写在某个路由的配置项里,当该路由被调用时,触发这个钩子。 -
用在路由鉴权,组件异步加载情景中。 routes:[{
path:"/test",
component:()=>import("../components/Test.vue"),
beforeEnter(to,from,next){
if(to.path==="/test"){
alert("请登录");
next(false); // 禁止跳转
}else{
next()
}
}
}]
组件内部声明周期守卫:(写在组件内部,与组件的生命周期函数同级)
beforeRouteEnter (to, from, next) {
// 在渲染该组件的对应路由被confirm前调用
// 不!能!获取组件实例`this`
// 因为当守卫执行前,组件实例还没被创建
// 故构造指定该next 可以接收一个回调函数接收当前vm 实例----路由传参获取参数,得到初始化数据
next(vm => {/*通过 `vm` 访问组件实例 */ })
},
beforeRouteUpdate (to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
},
beforeRouteLeave (to, from, next) {
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`
}
路由守卫的执行顺序
21.打包流程
在vue环境中将代码编写完成后,使用webpack打包工具,将项目整体打包,托管到后端服务器。
-
项目托管到服务器后就不存在跨域问题了,所以需要在打包前将配置的跨域方案删除,避免出现路径问题。 -
打包指令:npm run build; -
将打包后生成的文件复制到服务器的public文件夹下进行托管。 -
vue-router的模式不同会导致服务器托管处理方式不同:
-
如果router是在hash模式下,访问页面的路径会变成/#/hash,需要在服务器的路由中配置路由:router.get("/*",controller.home.all) ,调用controller中的all方法```async all(){ let data=fs.readFileSync(__dirname+"/…/public/index.html") this.ctx.body=data.toString() }```给前端返回托管的页面。网页会根据对应的路径读取JS文件然后运行,当前网页的路由匹配到JS代码的路由,则会渲染相应的组件,网页并不会刷新。还需要在服务器的node_modules>egg-static>config>config.default.js文件中,将prefix属性配置为"/",让打包托管后的文件路径读取正确。
- hash模式的优点是兼容性好,不需要在后端进行任何设置和开发,并且不会发送除ajax和资源加载之外的其他请求;
- hash模式的缺点是无法准确捕获路由的信息,对于需要锚点功能的需求会与当前路由机制发生冲突,对于需要重定向的操作,后端无法获取url全部内容,导致后台无法得到url数据。
-
使用history模式:这种模式每次更改路由都会向后端发送请求,也需要在服务器的路由文件中配置"/*"路由,使前端每次请求时,都给前端返回相同的页面,由该页面运行JS代码,再通过对应的路由渲染相应的组件。当服务器路由与页面JS文件内部路由重名时,在直接访问服务器的路由,给前端返回JS代码,而不是页面。——解决:避免重名。
致后台无法得到url数据。
- 使用history模式:这种模式每次更改路由都会向后端发送请求,也需要在服务器的路由文件中配置"/*"路由,使前端每次请求时,都给前端返回相同的页面,由该页面运行JS代码,再通过对应的路由渲染相应的组件。当服务器路由与页面JS文件内部路由重名时,在直接访问服务器的路由,给前端返回JS代码,而不是页面。——解决:避免重名。
|