Vue商城小技巧:返回列表页时,如何记住滚动位置?

大家好,我是小杨,一个写了6年前端的老码农。最近在做商城项目时,遇到一个很常见的需求:从列表页进入详情页,返回时希望列表页能自动滚动到之前的位置,而不是从头开始。

这功能听起来简单,但如果不注意细节,用户体验就会很糟糕。今天我就来分享一下我的实现方案,保证简单易懂,直接上代码!


1. 问题场景复现

假设我们有一个商品列表页(GoodsList.vue),点击某个商品进入详情页(GoodsDetail.vue),然后返回时发现列表页又回到了顶部,用户体验很不友好:

html 复制代码
<!-- GoodsList.vue -->
<template>
  <div>
    <div v-for="item in goodsList" :key="item.id" @click="goToDetail(item.id)">
      {{ item.name }}
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      goodsList: [
        { id: 1, name: "商品1" },
        { id: 2, name: "商品2" },
        // ... 假设有100个商品
      ]
    }
  },
  methods: {
    goToDetail(id) {
      this.$router.push(`/detail/${id}`)
    }
  }
}
</script>

这时候,用户滚动到第50个商品,点击进入详情页,再返回时,列表页又回到了顶部,体验很糟糕!


2. 解决方案:使用keep-alive + scrollBehavior

2.1 用<keep-alive>缓存列表页

Vue的<keep-alive>可以让组件不销毁,保留之前的状态(包括滚动位置)。

html 复制代码
<!-- App.vue 或 路由出口处 -->
<template>
  <div id="app">
    <keep-alive>
      <router-view v-if="$route.meta.keepAlive" />
    </keep-alive>
    <router-view v-if="!$route.meta.keepAlive" />
  </div>
</template>

然后在路由配置里标记哪些页面需要缓存:

javascript 复制代码
// router.js
const routes = [
  {
    path: '/list',
    name: 'GoodsList',
    component: GoodsList,
    meta: { keepAlive: true } // 标记需要缓存
  },
  {
    path: '/detail/:id',
    name: 'GoodsDetail',
    component: GoodsDetail
  }
]

2.2 记录滚动位置,并在返回时恢复

我们可以利用Vue Router的scrollBehavior来管理滚动行为:

javascript 复制代码
// router.js
const router = new VueRouter({
  routes,
  scrollBehavior(to, from, savedPosition) {
    // 如果是从详情页返回,并且有保存的位置,就恢复
    if (from.name === 'GoodsDetail' && savedPosition) {
      return savedPosition
    }
    // 否则默认滚动到顶部
    return { x: 0, y: 0 }
  }
})

2.3 优化:手动记录滚动位置(更精准)

如果scrollBehavior不够精准,我们还可以手动记录滚动位置:

javascript 复制代码
// GoodsList.vue
export default {
  data() {
    return {
      scrollTop: 0
    }
  },
  activated() {
    // 从缓存恢复时,滚动到之前的位置
    document.documentElement.scrollTop = this.scrollTop
  },
  beforeRouteLeave(to, from, next) {
    // 离开时记录滚动位置
    this.scrollTop = document.documentElement.scrollTop
    next()
  }
}

3. 最终效果

  • ✅ 进入详情页后返回,列表页会自动滚动到之前的位置
  • ✅ 用户体验流畅,不会出现"突然跳回顶部"的尴尬情况
  • ✅ 代码简单,维护成本低

4. 可能遇到的问题

  • keep-alive缓存太多页面导致内存问题? → 可以结合include/exclude控制缓存范围
  • 滚动位置不准? → 检查CSS布局(比如overflow设置)
  • 动态路由(如分页)怎么处理? → 可以用key强制刷新组件

5. 总结

在Vue项目中,保持滚动位置其实很简单,核心就是:

  1. <keep-alive>缓存页面
  2. scrollBehavior或手动记录滚动位置
  3. 注意动态路由的特殊情况

⭐ 写在最后

请大家不吝赐教,在下方评论或者私信我,十分感谢🙏🙏🙏.

✅ 认为我某个部分的设计过于繁琐,有更加简单或者更高逼格的封装方式

✅ 认为我部分代码过于老旧,可以提供新的API或最新语法

✅ 对于文章中部分内容不理解

✅ 解答我文章中一些疑问

✅ 认为某些交互,功能需要优化,发现BUG

✅ 想要添加新功能,对于整体的设计,外观有更好的建议

✅ 一起探讨技术加qq交流群:906392632

最后感谢各位的耐心观看,既然都到这了,点个 👍赞再走吧!

相关推荐
yume_sibai1 小时前
06-Rust Web 开发实战(Axum 框架 + 数据库 + JWT 认证 + 中间件 + 部署)
前端·数据库·rust
计算机魔术师2 小时前
特朗普上台打给黄仁勋:AI末日论是骗局,我们绝不让它发生
前端
troy1282 小时前
Python 基础语法(八):Web 后端开发、数据分析与可视化、网络爬虫、人工智能 / 大模型应用
前端·python·数据分析
计算机魔术师3 小时前
CEO说要慢下来,黑客说别做梦了——同一篇论文,两种命运
前端
kyriewen3 小时前
我花3天抓了一个幽灵bug,凶手藏在第4层
前端·javascript·程序员
IT_陈寒4 小时前
Java里用Stream.parallel()翻车实录,这性能还不如单线程
前端·人工智能·后端
Bs_MoneyMagnet4 小时前
基于springboot+vue的生态果园采摘预约系统的设计与实现 源码+文档
java·vue.js·spring boot·后端·毕业设计·计算机毕业设计
wangchunyu1144 小时前
JavaScript 零基础入门教程
前端
hanchenxing5 小时前
前端异步任务三方案:Celery vs Redis Stream vs BullMQ 实战对比消息队列
前端·数据库·redis·异步任务·方案对比
mONESY5 小时前
LangGraph.js 从零上手:把 Agent 工作流从一条线变成一张网
javascript