vue项目 keep-alive组件使用 不重复发请求且能回到原本的高度

349 阅读2分钟

1. 组件缓存

目标效果 进入首页 -> 点击文章 -> 跳转到文章详情 -> 点击返回,此时没有再次请求数据,恢复刚才的初始高度

image-20220807145550245

image-20220807145615160

image-20220807145701169

1 router/index.js里面设置缓存 元数据meta

怎么判断,给哪个路由设置?$route.meta.keepalive这个数据要在哪个组件里面获取,就去哪里设置,我的是在App.vue组件里面获取,就给path为'/'来设置

  {
    path: "/", // 默认路由
    // name: "layout",
    component: () => import("@/views/layout/index.vue"),
    meta: {
      keepalive: true, // 需要做缓存
    },
  1. app.vue组件里面使用keep-alive组件

你可以在你要设置缓存的组件里包裹

切记外层的router-view的意思是,有些组件,没有元信息,不需要增加缓存,所以v-if要取反。这里不是用一个v-else

<keep-alive>
  <router-view v-if="$route.meta.keepalive" ref="demo"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepalive"></router-view>
  1. 做完上面的操作,就能够不重新发请求了。但是下面操作完,才能高度回到刚才的位置。
  1. 要给一个dom元素设置id为demo,这个dom元素可以处于很深的位置都没关系,下面的图片只是我的示例,你的id的目标dom可能不同。直接刚

    第一层

    image-20220807145135923

    第二层 二级路由

    image-20220807145158390

    第三层

image-20220807145222939

第四层

image-20220807145246248

但是activated和deactivated这两个生命周期在哪里获取?第二层。因为第一层设置了keep-alive,第二层就是被keep-alive包裹的组件。里面写下面的代码

 beforeRouteLeave(to, from, next)
    // 离开页面之前将高度存储到sessionStorage动清除,有点麻烦。
    console.log(document.getElementById("demo"));
    console.log(document.getElementById("demo").scrollTop);
    sessionStorage.setItem(
      "scrollH",
      document.getElementById("demo").scrollTop
    );
    next();
  },
​
 activated() {
    // 在activated生命周期内,从sessionStorage中读取高度值并设置到dom
    if (sessionStorage.getItem("scrollH")) {
      document.getElementById("demo").scrollTop =
        sessionStorage.getItem("scrollH");
    }
  },
  1. beforeRouteLeave在离开当前路由之前,获取id为demo的dom元素的距离顶部的滚动值

    通过sessionStorage存储这个高度。为什么这里用beforeRouteLeave,它的含义是,离开当前组件之前,进行的操作。不用deactivated生命周期,因为这个是生命周期,我测试了没能获取到dom元素。

  2. 再次回到当前页面时,通过keep-alive组件而有的activated生命周期里面,判断有无sessionStorage对应存的值,如果有的话。给对应的盒子是scrollTop的值

  3. 为什么这里要用sessionStorage,因为我们初次进入浏览器的时候,不希望sessionStorage 存了初始值。而localStorage需要手动清除,而sessionStorage关闭浏览器就会自动清除。

总结:

  1. keep-alive做组件缓存,如果从A组件 -> 切换到B组件,想要回到A组件,不再次重复渲染A组件,而是原本的模样就好了。就可以给A组件
<keep-alive>
// A组件
</keep-alive>
  1. 被keep-alive包裹的组件 生命周期的变化?【如下图去指定页面测一下,你就知道了】
一进入这个页面
beforeCreate -> created -> beforeMount -> mounted -> activated
一离开这个页面
deactivated -> beforeUpdate -> updated
第二次进入
beforeUpdate -> activated -> updated
  1. 可以把这个用进项目呀,又多了一个难点和亮点了。虽然我不确定这个对面试官来说是不是小儿科

image.png