Vue3 keep-alive + pinia 实现页面缓存

·  阅读 162

❤️ 原文地址 ❤️

场景:A首页=> B列表页(需要缓存的页面)=> C详情页

由A到B到C再返回B的时候,B页面缓存,滚动到上次滚动的位置,如果由B返回到A,再进入B,B重新加载

根据业务逻辑需要实现部分页面缓存,且记住滚动位置,以及清部分缓存和全部缓存(如退出登录)

1、store 保存要缓存的页面

通过pinia保存要缓存的页面, 来处理keep-alive include缓存数据

keepAlive.ts文件:

import { defineStore } from "pinia";
import { RouteRecordName } from "vue-router";

export const useKeepAlive = defineStore("keepAlive", {
  state: () => {
    return {
      caches: [] as any,
    };
  },
  getters: {},
  actions: {
    add(name: RouteRecordName| null | undefined) {
      this.caches.push(name);
    },
    remove(name: RouteRecordName| null | undefined) {
      this.caches = this.caches.filter((item: any) => item !== name);
    },
    clear() {
      this.caches = [];
    },
  },
});
复制代码

2、根代码引入keep-alive组件

APP.vue 根代码引入keep-alive组件:

<template>
  <router-view v-slot="{ Component }">
    <keep-alive :include="keepAlive.caches">
      <component :is="Component" :key="route.name" />
    </keep-alive>
  </router-view>
</template>
<script lang="ts" setup>
import { useRoute } from "vue-router";
import { useKeepAlive } from '@/storePinia/keepAlive';
const route = useRoute();
const keepAlive = useKeepAlive();
</script>
复制代码

keep-alive include 必须要组件命名,对应要缓存的页面要添加:

<script lang="ts">
export default { name: 'list1' }; //name与路由name相同
</script>
复制代码

3、router 缓存、清除缓存

import {
    createRouter,
    createWebHashHistory,
    RouteRecordRaw
} from 'vue-router';

import pinia from '@/store' 
import { useKeepAlive } from '@/store/keepAlive';
const keepAlive = useKeepAlive(pinia);

const routes: Array<RouteRecordRaw> = [
   。。。
]

const router = createRouter({
    history: createWebHashHistory(),
    routes,
})

router.beforeEach((to, from) => {
    let routeFromTo=`${String(from.name)}>${String(to.name)}`;
    console.log('路由',routeFromTo);
    let addCacheArr=['home>list1','home>list2'];
    let rmCacheArr=['list1>home','list2>home'];
    if(addCacheArr.indexOf(routeFromTo)>-1){
        //添加缓存
        keepAlive.add(to.name)
        return
    }
    if(rmCacheArr.indexOf(routeFromTo)>-1){
        //删除缓存,清空缓存:keepAlive.clear()
        keepAlive.remove(from.name)
    }
})
export default router
复制代码

后面增加缓存页面,只需要在对应页面加上命名:export default { name: 'xxx' };,然后,根据缓存需求修改router.ts里对应的addCacheArrrmCacheArr

4、记住页面滚动位置

keepalive缓存并没有缓存页面滚动位置,需要手动记录

可以在 layout 文件全局处理,在 keepalive 两个钩子函数中进行处理scroll位置的缓存,onActivated中获取缓存中的位置,onDeactivated记录位置到缓存

<script setup lang="ts">
import { ref, onActivated, onDeactivated } from "vue";
const scrollTop = ref(0);
const handleScroll = () => {
  // 记录滚动位置
  scrollTop.value = document.getElementsByClassName("content")[0].scrollTop;
};
onActivated(() => {
  console.log("onActivated");
  if (scrollTop.value > 0) {
    let body = document.getElementsByClassName("content")[0];
    // 滚动到缓存的scroll值的位置
    body.scrollTo(0, scrollTop.value);
    scrollTop.value = 0;
  }
  window.addEventListener("scroll", handleScroll, true);
});
onDeactivated(() => {
  console.log("onDeactivated");
  // 页面退出时关闭事件,防止其他页面出现问题
  window.removeEventListener("scroll", handleScroll, true);
});
</script>
复制代码
分类:
前端
标签:
收藏成功!
已添加到「」, 点击更改