keep-alive缓存文章列表案例完整代码(Vue3)
环境准备
创建一个项目
vue create 项目名
也可以用 vite
npm create vite@latest 项目名 --template vue
安装 vue router
npm install vue-router@4
目录结构
完整代码
main.js
import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";
createApp(App).use(router).mount("#app");
App.vue
这里和vue2一样也有两种写法,可以看 keep-alive缓存文章列表案例完整代码(Vue2)
这边就用第二种。
<template>
<RouterView v-slot="{ Component }">
<KeepAlive>
<component :is="Component" v-if="route.meta.keepAlive" />
</KeepAlive>
<component :is="Component" v-if="!route.meta.keepAlive" />
</RouterView>
</template>
<script setup>
import { useRoute } from "vue-router";
const route = useRoute();
</script>
ArticleList.vue
<script setup>
import {
onMounted,
onActivated,
onDeactivated,
ref,
nextTick,
onUnmounted,
} from "vue";
const articles = ref([]);
const scrollTop = ref(0);
function fakeFetch() {
return Array.from({ length: 100 }, (_, i) => ({
id: i + 1,
title: "文章标题 " + (i + 1),
}));
}
function handleScroll() {
scrollTop.value = window.scrollY || document.documentElement.scrollTop;
// console.log("滚动位置:", scrollTop.value);
}
onMounted(() => {
// console.log("mounted:" + scrollTop.value);
articles.value = fakeFetch();
window.addEventListener("scroll", handleScroll);
});
//onUnmounted(() => {
// console.log("unmounted"); // 有就说明没缓存成功
//});
onActivated(() => {
nextTick(() => {
// console.log("activated:", scrollTop.value);
window.scrollTo(0, scrollTop.value);
});
window.addEventListener("scroll", handleScroll);
});
onDeactivated(() => {
// console.log("deactivated:", scrollTop.value);
window.removeEventListener("scroll", handleScroll);
});
</script>
<template>
<div>
<div v-for="item in articles" :key="item.id" class="item">
<router-link :to="{ name: 'ArticleDetail', query: { id: item.id } }">
{{ item.title }}
</router-link>
</div>
</div>
</template>
<style>
.item {
padding: 16px;
border-bottom: 1px solid #eee;
}
</style>
ArticleDetail.vue
<script setup>
import { onMounted } from "vue";
import { useRoute } from "vue-router";
// 获取路由信息
const route = useRoute();
onMounted(() => {
// 模拟请求内容
// console.log("详情页 mounted,ID:", route.query.id);
});
</script>
<template>
<div>
<h2>文章详情 {{ route.query.id }}</h2>
<p>内容详情...</p>
<router-link to="/list">返回列表</router-link>
</div>
</template>
router.js
import { createRouter, createWebHistory } from "vue-router";
import ArticleList from "@/components/ArticleList.vue";
import ArticleDetail from "@/components/ArticleDetail.vue";
const routes = [
{
path: "/list",
name: "ArticleList",
component: ArticleList,
meta: { keepAlive: true },
},
{
path: "/detail",
name: "ArticleDetail",
component: ArticleDetail,
meta: { keepAlive: false },
},
];
const router = createRouter({
history: createWebHistory(),
routes,
});
export default router;