目录

前言

问题描述

问题分析

问题解决

总结


前言

基于vue-cli脚手架开发的单页应用有他特殊的特点和优势。因为是单页应用,所以在进行F5刷新的时候和之前常规的html页面还有区分。主要区别在于,vue-router接管了浏览器的前进、后退、刷新等事件,通过对相关事件的监听,动态的操作popstate,pushstate,replacestate等api来完成浏览器url的变化;但其实对于页面本身而言,并没有我们所理解的常规刷新或者后退前进操作,毕竟是单页应用,内部的核心还是动态的div切换或者dom元素的动态渲染。

本篇通过对F5刷新操作的跟踪,我们来记录和了解一下vue组件是如何对对刷新操作进行处理的,各个组件的生命周期又是如何进行操作的,又有哪些点是需要我们注意的

问题描述

我们先来看一个具体的问题,实际项目中,登录成功之后的页面是一个左右结构的页面,假设为组件A,左侧是菜单区域,右侧是显示区域,我们的做法是在右侧区域添加一个<router-view>,通过左侧菜单的点击,动态的改变右侧router-view中的页面效果。首次登陆成功之后,要显示一个默认页面,我们在组件A的create中获取菜单树,然后判断菜单的id是否顶级,如果是则自动显示,假设默认组件是B。然后选择左侧菜单,跳转新页面,右侧区域渲染,假设我们显示了C组件,此时F5刷新,页面会自动回到组件B,也就是说,刷新操作无法刷“当前页”,只要刷新总会返回首页。

问题分析

我们在根组件A的beforeRouteEnter钩子函数中将to、from打印出来。然后我们通过左侧菜单点击,页面跳转到manager_device_list路由页面,然后点击F5刷新,打印的to 和 from如下

可以看到from的null,to就是我们当前的路由页面,但是为何会自动跳转到首页B去了呢?

这里就要说一下F5刷新时候组件的生命周期。

F5刷新的时候,会从跟组件重新走生命周期,即其实是从root.vue开始重新走声明周期,然后一级一级往下走,根据to路由最终到具体的渲染页面,问题就是出在这里,因为我们在跟组件A的create方法中循环菜单并自动跳转到首页了,所以在F5之后重新走跟组件声明周期时,在create中直接就把路由改变了,而不会再回到原来的to。

问题解决

通过再跟组件A的beforeRouteEnter钩子函数中判断from.name是否为null,来操作是否走自动到首页的逻辑。相关代码如下:

beforeRouteEnter(to, from, next) {
      console.log("to--->",to);
      console.log("from--->",from);
      if(ctool.strIsEmpty(from.name)){
        next();
      }else{
        next(vm => vm.initViews());
      }
    },

这里initViews中就是循环菜单找到首页并跳转到首页的逻辑。通过上面这种处理,完美解决该问题。

总结

(1) 不管是在浏览器中还是通过this.$router.push跳转某个页面时候,路由都是会从跟组件开始走,最终定位到具体的子组件,并在其对应的router-view中渲染,尤其是router-view嵌套router-view时候会看的更清晰,子组件始终是在父组件的生命周期走完再开始渲染。即:如果出现刷新后,页面没有留在当前页,那肯定是代码逻辑处理的有问题。

(2) F5刷新操作会清空store中的数据,所以般情况下,我们可以通过监听浏览器的刷新事件,在跟组件中对store中的数据通过localstorage进行保存和还原。

Logo

前往低代码交流专区

更多推荐