keep-alive缓存文章列表案例完整代码(Vue2)
环境准备
先创建一个 vue2 项目
vue create 项目名
安装 vue-router
,vue2 是 3,vue3 是 4
npm insatll vue-router@3
目录结构
完整代码
main.js
这里要注册路由
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
Vue.config.productionTip = false;
new Vue({
router,
render: (h) => h(App),
}).$mount("#app");
App.vue
两种写法:
可以用include里面写需要缓存的组件名称 name,这样的话就要在
router/index.js
中给组件写name。router/index.js
routes: [ { path: "/list", component: ArticleList, name: "ArticleList", }, // ...
App.vue
<template> <div> // <keep-alive :includes="['ArticleList',...]"> <keep-alive includes="ArticleList"> <router-view /> </keep-alive> </div> </template>
在 meta 中写明这个组件是否需要被缓存,然后在
Vue.js
中根据不同的值判断这个组件是否需要被 keep-alive 包裹,即是否被缓存。
router/index.js
routes: [ { path: "/list", component: ArticleList, meta: { keepAlive: true }, name: "ArticleList", }, // ...
App.vue
<template> <div> <keep-alive> <router-view v-if="$route.meta.keepAlive" /> </keep-alive> <router-view v-if="!$route.meta.keepAlive" /> </div> </template>
ArticleList.vue
<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>
<script>
export default {
name: "ArticleList",
data() {
return {
articles: [],
scrollTop: 0,
};
},
mounted() {
// console.log("mounted");
this.articles = this.fakeFetch();
window.addEventListener("scroll", this.handleScroll);
},
// 进入文章列表页面时
activated() {
this.$nextTick(() => {
// console.log("activated:", this.scrollTop);
window.scrollTo(0, this.scrollTop);
window.addEventListener("scroll", this.handleScroll);
});
},
// 离开文章列表页面时
deactivated() {
// console.log("deactivated:" + this.scrollTop);
// 将当前的位置保存下来
window.removeEventListener("scroll", this.handleScroll);
},
methods: {
fakeFetch() {
return Array.from({ length: 100 }, (_, i) => ({
id: i + 1,
title: "文章标题 " + (i + 1),
}));
},
handleScroll() {
this.scrollTop = window.scrollY || document.documentElement.scrollTop;
// console.log("滚动位置:", this.scrollTop);
},
},
};
</script>
<style>
.item {
padding: 16px;
border-bottom: 1px solid #eee;
}
</style>
ArticleDetail.vue
<template>
<div>
<h2>文章详情 {{ $route.query.id }}</h2>
<p>内容详情...</p>
<router-link to="/list">返回列表</router-link>
</div>
</template>
<script>
export default {
name: "ArticleDetail",
mounted() {
// 模拟请求内容
console.log("详情页 mounted,ID:", this.$route.query.id);
},
};
</script>
router.js
import Vue from "vue";
import Router from "vue-router";
import ArticleList from "@/components/ArticleList.vue";
import ArticleDetail from "@/components/ArticleDetail.vue";
Vue.use(Router);
export default new Router({
routes: [
{
path: "/list",
component: ArticleList,
meta: { keepAlive: true },
name: "ArticleList",
},
{
path: "/detail",
component: ArticleDetail,
meta: { keepAlive: false },
name: "ArticleDetail",
},
],
});