在vue单页面中,因接口响应速度较慢,用户每次进入都要花费过多时间进行等待,体验不好,为增加用户使用体验,需要--列表页进入详情页-按需加载,详情页有关闭,编辑,保存。等按钮,在关闭页面的时候 用户没有进行操作,需要关闭返回列表页时 不做重新加载-刷新操作。点击 保存-编辑等按钮再刷新接口或重新渲染。
且,列表的的搜索及页码,在后退回来时,不做变化,依旧保留。
我首先实现的是,列表的搜索数据与页码的保留。
1,新建一个公共js,利用sessionStorage 存储来实现
a.js
export const pageInfo = {
存储列表的给接口的传值
storageSearch(search){
if(search){
存储对象或数组值的时候,先转行成字符串,使用的时候再转行成数组或对象,
这样做的目的是:sessionStorage存储一般用于存储字符串用,存储数组或对象,
拿取的时候容易发生bug
sessionStorage.setItem('search', JSON.stringify(search));
}
let getItem=JSON.parse(sessionStorage.getItem('search'));
return getItem;
},
存储当前页面
storageSetPageNum(val){
sessionStorage.setItem('pageNum', val);
},
//给本页重新赋值
getPageNumFN(thisb,formDatas) {
let detail=this.getStorage();
如果进入详情页,再返回则可以保留数据
if(detail){
//把缓存数据赋值给列表
thisb.formData=this.storageSearch();
thisb.pageInfo.pageNum=
thisb.formData.pageNum||parseInt(sessionStorage.getItem('pageNum'))||1;
}
},
}
list.vue 列表页
import {pageInfo} from 'a.js';
newajax(){
if(pageInfo.getStorage()){
// 调用js,回填搜索数据--页码也在次方法里赋值了
pageInfo.getPageNumFN(this);
}
}
// 跳转下一个路由时执行,(离开当前路由)
beforeRouteLeave(to, from, next) {
删除详情标识
pageInfo.removeStorageDetail();
存储当前数据
pageInfo.storageSearch(this.formData);
next();
},
details.vue 详情页
mounted() {
因为要等list执行玩清除步骤,此处做了延迟-不然会比list抢先执行
setTimeout(()=>{
pageInfo.storageSetDetail();
},1000);
}
缓存列表页,按需加载刷新
路由:
路由位置 添加缓存标识
{
path: '/closeContactManageGz/CloseContactSfList',
name: 'CloseContactSfList',
component: () =>
import(
/* webpackChunkName: "closeContactManage" */ '@pages/closeContactManageGz/CloseContactSfList.vue'),
meta: {
title: '页面标题',
keepAlive: true, //缓存数据
},
},
app.vue
<keep-alive :include="cachedViews">
<router-view></router-view>
</keep-alive>
import { mapActions, mapGetters,mapState} from 'vuex';
computed: { ...mapGetters('app', ['cachedViews']), },
list.vue
在缓存页面--mounted 与 activated 里面的东西 不能重复,因为在刷新的时候 两个钩子都会执行
这样就会重复执行代码 消耗性能了,
created() {},created() {},
// 销毁存储(详情的储存)
destroyed(){},
mounted() {},
// 跳转下一个路由时执行,(离开当前路由)
beforeRouteLeave(to, from, next) {
pageInfo.removeStorageDetail();
keepAliveReload.delReload();
pageInfo.storageSearch(this.formData);
next();
},
activated () {
//判断是否需要刷新--如果没有详情标识-则刷新
let keepAlive_reload=keepAliveReload.getReload();
if(!keepAlive_reload){
this.newajax();
// this.getProviceCode();
}else{
//这句代码的意义,有时候点击菜单进入没有加载接口,所以需要这个判断
if(this.tableData.length<=0&&this.loading){
this.newajax();
}
}
},
details.vue
data(){
keepAlive_reload:false
},//to表示将要跳转页面的url,在页面中通过 keepAlive_reload 参数控制页面跳转到的页面是否需要缓存 beforeRouteLeave(to, from, next) { if(!this.keepAlive_reload){ //需要缓存列表-不要刷新列表 keepAliveReload.noReload(); } next(); },
保存fn(){
keepAlive_reload=true
},
关闭fn(){
keepAlive_reload=false
}
因为此功能进行得不是很顺利,所以完成之后记录一下,需要比较重要的两个问题:
1.缓存页面,mounted 与 activated 刚开始两个里面都写了初始化获取接口,导致加载两遍,
思去想来 决定写入activated里面,先把mounted放空,目前还未出现什么问题
2.在多个列表页缓存后, 点击菜单,会乱跳,如果点击a列表后,会又显示成b列表,这个比较
重大的bug,是不允许的,后来经过一番研究,发现是 因为没有清除缓存所致,需要在返回主页或在登录的地方,执行清除缓存组件,这样就ok了
login.vue 登录页
import { mapActions } from 'vuex';
//离开此页面时,清空缓存组件
async beforeRouteLeave(to, from, next) {
await this.delAllViews();
next();
},
methods: { ...mapActions('app', ['delAllViews']),//清空缓存的组件
}
清空cachedViews 数组 , 在app.vue 里面调用的
<div id="app">
<!-- <keep-alive>
<router-view v-if="$route.meta.keepAlive"/>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive" /> -->
<keep-alive :include="cachedViews">
<router-view></router-view>
</keep-alive>
</div>