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

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

相关推荐
不断努力的根号七1 小时前
qt框架,使用webEngine如何调试前端
开发语言·前端·qt
德育处主任1 小时前
p5.js 线段的用法
javascript·数据可视化·canvas
伍哥的传说2 小时前
React性能优化终极指南:memo、useCallback、useMemo全解析
前端·react.js·性能优化·usecallback·usememo·react.memo·react devtools
JuneXcy2 小时前
leetcode933最近的请求次数
开发语言·javascript·ecmascript
saadiya~3 小时前
Vue + WebSocket 实时数据可视化实战:多源融合与模拟数据双模式设计
vue.js·websocket·信息可视化
midsummer_woo9 小时前
基于springboot的在线教育系统(源码+论文)
vue.js·spring boot·mysql
2301_781668619 小时前
前端基础 JS Vue3 Ajax
前端
上单带刀不带妹9 小时前
前端安全问题怎么解决
前端·安全
Fly-ping9 小时前
【前端】JavaScript 的事件循环 (Event Loop)
开发语言·前端·javascript