移动端使用keep-alive将页面缓存和滚动缓存具体实现方法 - 详解

发布于:2025-05-01 ⋅ 阅读:(42) ⋅ 点赞:(0)

1. 配置组件名称

确保列表页组件设置了name选项,(组合式API额外配置):

<!-- vue2写法 --> 
export default {
  name: 'UserList' // 必须与 <keep-alive> 的 include 匹配
}

<!-- vue3写法 --> 
defineOptions({
  name: "UserList"
});

2. 路由配置

在路由配置中添加 meta 标识是否需要缓存:

{
    path: "/userList",
    name: "UserList",
    component: () => import("@/views/user/list.vue"),
    meta: {
      title: "用户列表",
      keepAlive: true // 自定义缓存标识
    }
  },

3. 动态缓存控制

在 App.vue 中使用 <keep-alive> 包裹路由视图,并动态判断缓存:

<!-- App.vue -->
<template>
  <router-view v-slot="{ Component, route }">
    <keep-alive :include="cachedViews">
      <component
        :is="Component"
        :key="route.fullPath"
        v-if="route.meta.keepAlive"
      />
    </keep-alive>
    <component
      :is="Component"
      :key="route.fullPath"
      v-if="!route.meta.keepAlive"
    />
  </router-view>
</template>

<script setup lang="ts">
import { ref, watch } from "vue";
import { useRoute } from "vue-router";

const cachedViews = ref([]);
const route = useRoute();

watch(
  () => route.meta.keepAlive,
  newVal => {
    if (newVal && !cachedViews.value.includes(route.name)) {
      cachedViews.value.push(route.name);
    }
  }
);
</script>

4. 生命周期钩子

在列表页组件中使用 activated 钩子(vue3 使用 onActivated )  处理返回时的逻辑:

<div class="list_box" @scroll="handleScroll" ref="listRef"> 
    <van-list
        v-model:loading="loading"
        :finished="finished"
        finished-text="没有更多了"
        @load="getList"
    >
    .......
    </van-list>
</div>

const listRef = ref(null);
// 缓存分页和滚动位置
const cachedState = ref({
  page: 1,
  scrollTop: 0
});

// 滚动事件处理
const handleScroll = e => {
  // 实时保存滚动位置
  cachedState.value.scrollTop = e.target.scrollTop;
  // console.log("cachedState.value.scrollTop", cachedState.value.scrollTop);
};

onActivated(async () => {
  console.log("组件激活,执行激活时的操作", cachedState.value.page);
  if (cachedState.value.page > 1) {
    searchQuery.page = cachedState.value.page;
  }
  await nextTick();
  // 恢复滚动位置
  if (listRef.value) {
    listRef.value.scrollTop = cachedState.value.scrollTop;
  }
});

onDeactivated(() => {
  // 保存当前状态
  cachedState.value.page = searchQuery.page;
  console.log("组件停用", cachedState.value.page);
});

6. 高级场景:条件缓存

// 在全局前置守卫中
router.beforeEach((to, from) => {
  if (from.name?.toString().includes('Detail') && to.name === 'UserList') {
    to.meta.keepAlive = true // 从详情页返回时缓存
  } else if (to.name === 'ListPage') {
    to.meta.keepAlive = false // 从其他页面进入时不缓存
  }
})


网站公告

今日签到

点亮在社区的每一天
去签到