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

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

​

相关推荐
程序员Sunday14 小时前
JavaScript 事件循环面试题,宏任务与微任务怎么执行|Sunday面试指南
开发语言·javascript·面试·校招·事件循环·程序员sunday
Setsuna_F_Seiei14 小时前
前端转型 Agent 开发 06 之 Agent Memory 记忆系统(让 Agent 更智能,更懂你)
前端·agent·ai编程
志尊宝15 小时前
Vue3 零基础每日笔记(073):keep-alive 页面缓存实战——列表页返回不丢状态
vue.js·笔记·缓存·#vue #前端 #前端开发·#javascript·#vue.js
zhangzeyuaaa15 小时前
Ruby 多线程、GVL(GIL)与 Mutex 完全指南
开发语言·前端·ruby
默_笙15 小时前
🌊 向量库和 ES 都查不出"关系",我只好给奶茶建了一张人脉网
前端·javascript
优选资讯16 小时前
标签打印软件怎么对接 Excel 数据
前端·excel
思无邪6616 小时前
用 AI 做 JS 逆向:从抓包到复现的完整方法论
开发语言·javascript·人工智能
一个风轻云淡17 小时前
GCC 和 GDB命令简单解读
java·linux·前端
u01110267518 小时前
图片处理接口如何统一错误信息 前端提示与后端错误码设计
前端·状态模式
福兮说18 小时前
浏览器里把 iPhone 的 HEIC 转成 JPG:Chrome 解不开、转完大了七成、拍摄时间全丢,六个坑实测
前端·javascript·图像处理·chrome·ios·iphone·heic