vue中beforeRouteEnter、beforeRouteLeave的应用场景
每个vue单文件组件中,可以加入三种route navigation guards(导航守卫钩子):beforeRouteEnter,beforeRouteUpdate,beforeRouteLeave,比较常用的是beforeRouteEnter和beforeRouteLeave,这里总结下项目中遇到的应用场景。
beforeRouteEnter
比较常见的一种应用场景就是,当前页面是数据列表页并且开启了缓存,跳转到其他子页面再跳转回来时,需要根据不同的页面或参数来判断是否重新加载列表页的数据。有一种方法就是给列表页的路由配置meta字段——路由元,设置一个refresh属性,并在activated钩子里做对应处理。
{ path: "/bookList", name: "bookList", component: resolve => require(["@/views/book/List"], resolve), navbarOption: "书籍列表", meta: { keepAlive: true, // 组件缓存 refresh: false // activated钩子触发时是否重新加载数据 } },
代码中用到了sessionStorage、localStorage,但有时候走了一圈流程后需要重置数据,就可以在beforeRouteEnter
或beforeRouteLeave
处理这些缓存。
beforeRouteLeave
离开本路由前需要重置样式。
代码中用到了sessionStorage、localStorage,但有时候走了一圈流程后需要重置数据,就可以在beforeRouteEnter或beforeRouteLeave处理这些缓存。
离开本路由前显示确认框:确认离开本页面。
从本页面返回时,不是回到上一个页面,而是需要指定别的页面,那么就要在beforeRouteLeave方法里处理,最后一定要加上next();
<template> <div class="test_box"> 组件内部导航守卫钩子 </div> </template> <script> let map, needReload = false; // 需要重新加载页面 export default { data() { return { mapfromlng: 0, mapfromlat: 0, mapFromcity: '北京' } }, methods: { initData(){ console.log('initData'); }, initmap(){ if(needReload) { window.location.reload() } map = new AMap.Map("container", { resizeEnable: true, zoom: 11, center: [this.mapfromlng, this.mapfromlat], mapStyle: "amap://styles/macaron" }); // 通过插件获取LEAST_TIME AMap.plugin(["AMap.Transfer"], () => { let transOptions = { city: this.mapFromcity, //公交城市 policy: AMap.TransferPolicy.LEAST_TIME //乘车策略 }; transfer = new AMap.Transfer(transOptions); //构造公交换乘类 //根据起点、终点坐标查询公交换乘路线 transfer.search(new AMap.LngLat(this.mapfromlng, this.mapfromlat), new AMap.LngLat(this.maptolng, this.maptolat), (s, res) => { if (res.plans && res.plans.length > 0) { // to do ... } }); }); } }, // 路由访问时 beforeRouteEnter(to, from, next) { // 1.在meta中,存储refresh字段,用来判断是否需要重新加载数据 if(from.name === 'refund' || from.query.fromDetail === 1){ to.meta.refresh = true; } // 2.重置缓存 window.sessionStorage.setItem('fromPhaseOne',0); // 3.需要刷新当前页面 if (from.fullPath.indexOf('index') != -1 && from.fullPath.indexOf('source') != -1) { needReload = true; } next(); // 或者,在next()回调里访问this // next(vm => { // vm 就是当前组件的实例相当于this,所以在 next 方法里可以把 vm 当 this 来用了。 // console.log('beforeRouteEnter-this',vm); // }); }, // 路由更新时 beforeRouteUpdate(to, from, next) { // 以动态路由的方式(如`/foo/:id`),再次访问到当前组件时,调用beforeRouteUpdate // 可以访问组件实例 `this` next(); }, // 路由离开时 beforeRouteLeave(to, from, next) { // 导航离开该组件的对应路由时调用 // 可以访问组件实例 `this` // 1.回滚样式 document.querySelector(".router-bg").style.cssText = ""; // 2.重置缓存 window.sessionStorage.setItem('fromPhaseTwo',0); // 3.显示离开当前页面的确认框 this.$confirm({title:'订单尚未支付,确定离开?'}); // 4.跳转到指定路由或页面 if (["/pay"].indexOf(to.path) > -1 && this.$env.isMiniProgram) { next(false); // 跳转到小程序的某个页面 wx.miniProgram && wx.miniProgram.redirectTo({ url: "/page/mine/mine" }); } else { // 跳转到指定页面 this.$router.push({ path: "/detail", query: {status:2} }); next(true); } // next(); }, mounted () { this.initmap(); }, activated () { // 需要刷新页面 if (this.$route.meta.refresh) { this.$route.meta.refresh = false; this.initData(); } }, } </script>