Vue2 编辑返回保留分页页码解决方案

问题根源

this.$router.back() 只是单纯回退历史记录,列表页分页、搜索筛选、页码是存在组件 data 里的,路由回退后组件会重新加载,丢失之前分页状态。

四种主流方案(按推荐程度排序)

方案1:路由传参(最简单,无需缓存)

1. 列表页跳转编辑时,带上当前分页参数

// 列表页 点击编辑
handleEdit(row) {
  const page = this.pageNum; // 当前页码
  const size = this.pageSize; // 每页条数
  this.$router.push({
    path: `/product/edit/${row.id}`,
    query: { page, size } // 把分页存在query
  })
}

2. 编辑页保存时,携带页码返回列表

// 编辑确认按钮
async submit() {
  await api.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() {
  await saveApi();
  this.$router.back(); // 列表组件被缓存,页码数据全部保留
}

补充:如果需要编辑完强制刷新列表

监听 activated 钩子,判断是否从编辑页返回:

// ProductList.vue
activated() {
  // 判断上一页是编辑页,刷新数据
  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 存储分页状态(多页面共用)

适合多处进入编辑、需要全局保存分页

  1. store 定义分页变量
state: {
  productPage: {
    pageNum: 1,
    pageSize: 10
  }
},
mutations: {
  setProductPage(state, payload) {
    state.productPage = payload
  }
}
  1. 列表每次请求前更新store
this.$store.commit('setProductPage', {
  pageNum: this.pageNum,
  pageSize: this.pageSize
})
  1. 列表 created 读取store恢复
created() {
  const page = 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() {
  const cache = localStorage.getItem('productPage');
  if (cache) {
    const { pageNum, pageSize } = JSON.parse(cache);
    this.pageNum = pageNum;
    this.pageSize = pageSize;
  }
  this.getList();
}

推荐组合使用方案(项目通用)

  1. 列表路由加 keepAlive 缓存,返回直接保留分页,体验最好
  2. 如需编辑后刷新列表,搭配路由meta标记,在 activated 重新请求接口
  3. 若页面复杂、多入口跳转,补充路由query兜底

踩坑提醒

  1. this.$router.back() 无法携带参数,单纯回退一定会丢失组件内数据,不要只用back
  2. keep-alive 缓存后 created 不会再次执行,改用 activated 处理刷新逻辑
  3. 分页参数一定要转数字,query获取的是字符串,请求接口会报错

更多推荐