场景描述
业务遇到需求,管理平台的页面打开后输入的查询条件、已经点击的页码、已经查询的数据要求保留下来,在tab菜单切换时保留,在关闭菜单时重置清空。
解决方案
1.使用cookie、localStorage或者sessionStorage
这个方式能解决部分需求,比如记录下查询条件或者页码之类的,但是有缺陷,储存大小有限制。
cookie数据大小不会超过4K,session storage和local storage可以达到5M。不是好的办法,可以满足如全局检索条件这种需求。
2.使用vue的keep-alive
keep-alives是组件缓存,主要用于保留组件状态或避免重新渲染,意思是说vue页面的created等只执行一次。这能做什么呢?这可做的多了,这样的话我们可以将查询条件或者已查询到的数据在created时保留,切换tab时由于没有重新渲染不会重新created,但是在关闭菜单后再打开菜单又会重新渲染并执行created。
这时只需要在created时重置查询条件和页码及查询数据对象,再执行查询后台并保留这时的查询条件及数据即可实现需求。
这种方式可以解决页面使用的是同一组件这种场景。因为使用同一组件时,不使用keep-alive的话不管是进行tab菜单切换还是关闭后重新打开菜单都会重新渲染,都会执行created等之后的步骤。
代码实现
一、要使用keep-alive需要满足2点:
1.路由配置文件设置keepAlive=true
//index.js
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/bookOrder',
name: 'BookOrder',
// 设置keepAlive属性
meta: {
keepAlive : true
},
component: resolve => require(['@/views/order/BookOrder'], resolve)
}
],
mode:'history'
})
2.标注需要缓存的组件,用<keep-alvie>包裹
若以ruoyi的AppMain.vue
<template>
<section class="app-main">
<transition name="fade-transform" mode="out-in">
<keep-alive :include="cachedViews">
<router-view v-if="!$route.meta.link" :key="key" />
</keep-alive>
</transition>
<iframe-toggle />
</section>
</template>
<script>
import iframeToggle from "./IframeToggle/index"
export default {
name: 'AppMain',
components: { iframeToggle },
computed: {
cachedViews() {
return this.$store.state.tagsView.cachedViews
},
key() {
return this.$route.path
}
}
}
</script>
3.页面vue文件的name要与Router中的name一致
比如上面Router中name是BookOrder,则bookOrder.vue中也必须是这个
export default {
name: "BookOrder",
data{}
}
二、实现
组件MyTempPage.vue
//关键代码
data() {
.....
// 总条数 从需要留存的数据中读取
total: this.config.remainData.total,
// 表格数据 从需要留存的数据中读取
tableList: this.config.remainData.tableList,
.....
// 查询参数
queryParams: this.config.queryParams,
.....
},
created() {
//清空查询条件、页码、缓存的数据
this.queryParams=this.config.queryParams= {};
this.config.remainData = {tableList:[],total:0}
this.queryParams.pageNum = 1;
this.queryParams.pageSize = 10;
this.resetForm("queryForm");
//请求后台
this.getList();
},
methods: {
//请求后台
getList() {
this.loading = true;
if(this.config.parseQueryParams) this.config.parseQueryParams(this.queryParams);
this.api.list(this.queryParams).then(response => {
let list = response.rows;
if(this.config.parseData) list.forEach(this.config.parseData)
this.tableList = response.rows;
this.total = response.total;
this.loading = false;
//留存数据
this.config.remainData.tableList = response.rows;
this.config.remainData.total = response.total;
});
},
},
activated() {
//不需要记录数据的页面,重新执行查询
if(!this.config.isRemainData) {
//重新加载数据
this.getList();
}
}
三、效果展示
Q&A
Q:ruoyi需要自己做keep-alive吗?
A:不用,ruoyi已经实现了。反映在哪里了呢?注意看 系统管理-菜单管理-编辑-是否缓存
Q:我用的是ruoyi,菜单设置是否缓存选择的缓存,为啥actived和deactivated没生效啊?
A:注意页面vue文件的name要与Router中的name一致,另外注意ruoyi在做动态router时的代码
所以vue页面中的name也需要是首字母大写的