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

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

相关推荐
星空的资源小屋7 分钟前
跨平台下载神器ArrowDL,一网打尽所有资源
javascript·笔记·django
Dorcas_FE41 分钟前
【tips】动态el-form-item中校验的注意点
前端·javascript·vue.js
小小前端要继续努力44 分钟前
前端新人怎么更快的融入工作
前端
八月ouc1 小时前
解密JavaScript模块化演进:从IIFE到ES Module,深入理解现代前端工程化基石
javascript·es6·模块化·cmd·commonjs·amd·iife
四岁爱上了她1 小时前
input输入框焦点的获取和隐藏div,一个自定义的下拉选择
前端·javascript·vue.js
fouryears_234171 小时前
现代 Android 后台应用读取剪贴板最佳实践
android·前端·flutter·dart
boolean的主人1 小时前
mac电脑安装nvm
前端
用户1972959188911 小时前
WKWebView的重定向(objective_c)
前端·ios
烟袅1 小时前
5 分钟把 Coze 智能体嵌入网页:原生 JS + Vite 极简方案
前端·javascript·llm
18你磊哥1 小时前
Django WEB 简单项目创建与结构讲解
前端·python·django·sqlite