vue3浏览器后退前进不刷新页面

一、业务场景示例

页面A: 数据列表,有一些查询条件,如查询条件区域,查询结果为区域信息列表
页面B: 数据详情,点击列表任意一条记录,跳转到对应的区域详情

期望:在页面B,点击浏览器返回按钮,显示上一次页面A查询结果与查询条件(最好不从新请求)

二、实现

利用vue的keep-alive,使用keep-alive可以是组件在第一次创建时被缓存下来,离开页面时不销毁
使用了

keep-alive生命周期
1.activated:页面第一次进入的时候,钩子触发的顺序是created->mounted->activated
2.deactivated :页面退出的时候会触发deactivated,当再次前进或者后退的时候只触发activated

修改路由注册文件


    
      
    
    

在需要缓存的页面路由中配置keepAlive: true

{
  name: 'A',
  path: '/A',
  component: () => import(/* webpackChunkName: "home" */ '@/views/A.vue'),
  meta: {
    keepAlive: true,
  },
}

添加统一判断是否是返回

router.afterEach((to) => {  // 一定要再afterEach中判断而不是beforeEach,因为beforeEach在点击返回之后获取到的值不准确,每返回一次,会获取到延后一次的to、history
  if (window.history.state && window.history.state.forward) { // 或者判断 to.forward,window.history.state.forward是vue-router写入的,当返回或前进的时候才会有值
    to.meta.isBack = true;
  } else {
    to.meta.isBack = false;
  }
});

在使用的页面

 const isInit = ref(true);  // 解决window.history.state.forward是否存在判断是否返回不准确问题
onMounted(() => {
  submitSearchForm(); // 请求查询数据
});

const routes = useRoute();
const searchFormRef = ref();
onActivated(() => {
      if (!routes.meta.isBack && !isInit.value) { // 如果不是返回还是需要请求更新数据的
        searchFormRef.value.resetFields();  // 这是ant-design-vue提供的重置表单的方法,如果没用,可以手动重置
        submitSearchForm(); // 请求查询数据
      }
isInit .value = false;
});

三、采坑总结

1.不要动态修改to.meta.keepAlive的值控制是否缓存。

会存在第一次将to.meta.keepAlive设置为true是还是会发送请求,因为第一次是创建组件,没有缓存,需要缓存后,下一次进入才不会发送请求。因为如果最开始进入的时候to.meta.keepAlive值为false的话,渲染的是没有使用keep-alive的组件。

2.通过forward判断是否是返回,需要再afterEach中

因为beforeEach在点击返回之后获取到的值不准确,每点击一次返回,会获取到延后一次的to、history中的值

3.需要再中间中配置key值,来表示组件的唯一性和对应关系,如::key="$route.path"

如果不配置key值,当多个页面配置keepAlive:true时,在切换缓存页面时会报错Uncaught (in promise) TypeError: parentComponent.ctx.deactivate is not a function

4.不能完全依靠window.history.state.forward是否存在判断是否返回,如果返回后再刷新页面也是有值得,所以在mounted也要发送请求,避免返回后刷新页面没有值,但会导致第一次会重复请求,所以最好在判断下是不是第一次进入

你可能感兴趣的:(vue3浏览器后退前进不刷新页面)