Vue2 编辑返回保留分页页码解决方案
问题根源
this.$router.back()只是单纯回退历史记录,列表页分页、搜索筛选、页码是存在组件 data 里的,路由回退后组件会重新加载,丢失之前分页状态。
四种主流方案(按推荐程度排序)
方案1:路由传参(最简单,无需缓存)
1. 列表页跳转编辑时,带上当前分页参数
// 列表页 点击编辑handleEdit(row){constpage=this.pageNum;// 当前页码constsize=this.pageSize;// 每页条数this.$router.push({path:`/product/edit/${row.id}`,query:{page,size}// 把分页存在query})}2. 编辑页保存时,携带页码返回列表
// 编辑确认按钮asyncsubmit(){awaitapi.save(this.form);// 获取跳转过来时携带的分页参数const{page,size}=this.$route.query;if(page){// 跳回列表并带上分页,自动加载对应页this.$router.push({path:'/product/list',query:{page,size}})}else{this.$router.back();}}3. 列表页 created 读取 query 恢复分页
created(){// 路由带分页则赋值if(this.$route.query.page){this.pageNum=Number(this.$route.query.page);this.pageSize=Number(this.$route.query.size);}this.getList();// 重新请求对应页码数据}优点:简单无副作用;缺点:url会拼接分页参数
方案2:keep-alive 缓存列表组件(最优体验)
页面不会重新请求,直接保留上次滚动、分页、筛选状态
1. 路由配置开启缓存
<!-- App.vue / 路由出口 --> <router-view v-if="$route.meta.keepAlive" keep-alive></router-view> <router-view v-else></router-view>2. router/index.js 给列表路由加标记
{path:'/product/list',name:'ProductList',component:ProductList,meta:{keepAlive:true}// 标记需要缓存},{path:'/product/edit/:id',component:ProductEdit}3. 编辑完成直接回退即可
submit(){awaitsaveApi();this.$router.back();// 列表组件被缓存,页码数据全部保留}补充:如果需要编辑完强制刷新列表
监听activated钩子,判断是否从编辑页返回:
// ProductList.vueactivated(){// 判断上一页是编辑页,刷新数据if(this.$route.meta.fromEdit){this.getList();this.$route.meta.fromEdit=false;}}跳转编辑时打标记:
handleEdit(){this.$route.meta.fromEdit=true;this.$router.push(`/product/edit/${id}`)}方案3:Vuex / Pinia 存储分页状态(多页面共用)
适合多处进入编辑、需要全局保存分页
- store 定义分页变量
state:{productPage:{pageNum:1,pageSize:10}},mutations:{setProductPage(state,payload){state.productPage=payload}}- 列表每次请求前更新store
this.$store.commit('setProductPage',{pageNum:this.pageNum,pageSize:this.pageSize})- 列表 created 读取store恢复
created(){constpage=this.$store.state.productPage;this.pageNum=page.pageNum;this.pageSize=page.pageSize;this.getList();}方案4:本地存储 localStorage(刷新页面也不丢失)
// 列表切换页码时保存changePage(){localStorage.setItem('productPage',JSON.stringify({pageNum:this.pageNum,pageSize:this.pageSize}))this.getList()}// 列表初始化读取created(){constcache=localStorage.getItem('productPage');if(cache){const{pageNum,pageSize}=JSON.parse(cache);this.pageNum=pageNum;this.pageSize=pageSize;}this.getList();}推荐组合使用方案(项目通用)
- 列表路由加
keepAlive缓存,返回直接保留分页,体验最好 - 如需编辑后刷新列表,搭配路由meta标记,在
activated重新请求接口 - 若页面复杂、多入口跳转,补充路由query兜底
踩坑提醒
this.$router.back()无法携带参数,单纯回退一定会丢失组件内数据,不要只用back- keep-alive 缓存后
created不会再次执行,改用activated处理刷新逻辑 - 分页参数一定要转数字,query获取的是字符串,请求接口会报错