Vue实现页面返回停留原位置的多种方案

 更新时间:2025年03月14日 08:39:09   作者:MariaH  
文章主要讨论了在 Vue 开发中实现页面返回停留原位置的多种方案,包括 Vuex、keep-alive、v-show、客户端跳转等,并分别阐述了它们的优缺点和适用情况,强调开发前应周全考虑前端业务和用户体验,根据实际业务选择合适方案,需要的朋友可以参考下

一.问题背景

在开发 H5 项目的时候,本来没有考虑到页面返回停留到原位置这个需求,正常的进行 Vue 路由的跳转,直接进行 Vue 路由的跳转,正常情况如果不使用keep-alive进行组件缓存的情况下,跳转到一个页面后返回页面是要正常走 Vue 的声明周期进行刷新的,但是在 H5 端用户可能更希望在跳转后返回还是停留在原来的位置,所以就要对之前的代码进行修改来满足这个需求,其实在安卓或者 IOS 壳子中打开一个webview原来的这个webview会被正常的缓存到,还会停留在之前的位置,之前的操作也会被缓存到,可以理解为我们新打开了一个浏览器的标签页,新的标签页对原来的标签页面不会造成任何的影响,虽然本质上还是有些差别,所以实现上述的需求的方案有很多,所以就总结一下各种方案的优缺点,以及适用情况。

二.Vuex 实现方案

使用 Vuex 来实现返回停留在原来的位置基本的思路就是当离开这个页面的时候通过scrollTop来记录下具体的位置然后通过 Vuex 进行存储,然后返回的时候进入页面之前就从 Vuex 中取出来,等到页面加载完毕就滚动到具体位置。

  • 优点:不需要缓存 Vue 页面,不会对页面的的正常生命周期造成影响,只需要新增逻辑,不需要修改原来的代码,修改的时候不容易出现 bug。
  • 缺点:返回之后原来的页面会重新请求,虽然可也停留在原来的位置,但是当原页面加载完毕位置还是会因为组件的变化而微小变动,页面会出现闪动,原来的操作无法记录,重新请求容易给服务器造成压力。

这个方案其实实现的仅仅就是滚动到原来的位置,并且由于 H5 有的要使用客户端跳转可能会造成失效的情况,如果是最初开发阶段不建议使用此方案,本方案适用于在原来没有这个效果的页面上增加这个效果的时候使用。

beforeRouteLeave(to, from, next) {
  let position = document.querySelector("#app").scrollTop; //记录离开页面时的位置
  if (position == null) position = 0;
  this.$store.commit("pageLocation/setPagePostion", position); //离开路由时把位置存起来,
  next();
},

  computed: {
    ...mapState({
      pagePostionNum: (state) => state.pageLocation.pagePostion,
    }),
      },

      mounted() {
      this.isTabRoute();
    },

    methods: {
      isTabRoute() {
        if (this.$route.path === "/ETFZone") {
          document.querySelector("#app").scrollTop = this.pagePostionNum;
        }
      },
    }

提示:H5 中页面没有可以刷新的按钮所以在 Vuex 的数据不需要担心刷新会丢失,但是在 PC 需要考虑。

三.keep-alive 方案

keep-alive 的方案和 Vuex 的方案思路基本一致,将具体页面缓存,通过keepAlive在路由 meta 中的配置来选择合适的时间释放缓存,在页面离开的时候通过scrollTop记录位置,然后当返回这个页面的时候在activated这个生命周期进行激活滚动到原来的位置。

  • 优点:可以缓存页面原来的操作,用户体验感更好,实现思路更加符合主流实现方案。
  • 缺点:面对改造的业务会对原来代码进行更改,并且因为加了缓存,很多操作需要激活,容易出现 bug

这个方案适合在项目或者模块开发的初期考虑进取当作主要实现方案,对于维护的代码可能会出现 bug,不容易修改。

beforeRouteLeave(to, from, next) {
  this.rememberScroll = document.querySelector("#app").scrollTop;
  next();
},

  // 缓存组件激活时调用
  activated() {
    document.querySelector("#app").scrollTop = this.rememberScroll;
    console.log(document.querySelector("#app").scrollTop, "距离顶部的距离");
  },

四.v-show 方案

v-show方案相对于前两种是最简单的,并且可以一个页面全部梭哈,自己对代码请求更新时机也比较容易把控,不需要考虑位置的记录,激活等等问题。

  • 优点:简单易懂,代码可控度较高,不容易出现 bug 等缓存造成的问题。
  • 缺点:路由不可用,需要自己编写路由栈,页面过多会造成代码冗余,难以维护。
/**
 * @class VshowRouter 模拟路由
 * @from 当前页面路由
 * @to 要跳转的页面路由
 * @method addRouter 添加要跳转的路由
 * @method navigatorRoute 返回最近的路由
 * @method deleteRoute 删除栈顶元素-最近跳转的路由
 * @method clearRoute 清空整个路由栈
 * @method customRoute 自定义路由跳转-返回将要跳转的路径
 */
class VshowRouter {
  constructor() {
    this.route = []
  }

  addRouter(from) {
    this.route.push(from)
  }

  navigatorRoute() {
    if (this.route.length >= 1) {
      const lastRoute = this.route[this.route.length - 1]
      if (lastRoute >= 1) {
        this.deleteRoute()
        return lastRoute
      }
    }
  }

  deleteRoute() {
    if (this.route.length > 0) {
      this.route.pop()
    }
  }

  clearRoute() {
    if (this.route.length > 0) {
      this.route.splice(0)
    }
  }

  customRoute(from, to) {
    this.addRouter(from)
    return to
  }
}

export const vShowRouter = new VshowRouter()

在页面中我们就可以使用v-show来进行控制展示,每展示的页面要进入上述的栈中来控制路由。

<main>
  <SearchContent
  v-show="searchStep === 'one'"
  @goSearchUser="navUserResource"
  @createOther="createOther"
  :obj="obj"
  @chioceResultTag="chioceResultTag"
    />
    <SearchResult
  :searchStatus="searchStatus"
  @navUser="navJump"
  :ArrayData="ArrayData"
  v-show="searchStep === 'two'"
    />
    <UserBasicInformation
  @goNext="goNextStepTwo"
  :userBasic="userBasic"
  :userExperience="userExperience"
  v-show="searchStep === 'three'"
    />
    </main>

虽然v-show写起来比较简单,但是如果需要支持路由的情况就会变的相对复杂起来,需要自己模拟路由来实现路由栈来解决这个问题,如果页面很简单或者只需要在页面中的某个组件相互切换比较适合选择使用。

五.客户端跳转方案

在 H5 可以通过客户端跳转新开webview来解决上述的问题,并且不会造成其他的问题,我们来看下这种方案的优缺点。

  • 优点:直接跳转新的webview不会出现上述问题,仅需要更改跳转为客户端的跳转方法。
  • 缺点:参数传递,参数接收不容易监控,打开太多webview容易造成性能问题。

如果需要跳转的页面有一页或者一个 Vue 文件可以搞定,其实使用这种方法能够很大程度上解决这个问题,并且可以和v-show的方案一起使用。

toUrlBan(str) {
  T.fn.action10061({
    url: str,
    tzthiddentitle: "0",
    TITLETYPE: "1",
  });
},

六.问题总结

这篇文章到这里就结束了 🛜,其实面对这类问题应该尽量在开发前将相应的前端业务和用户体验考虑周全,因为如果前期考虑不到,后期新增这些功能的时候会非常的麻烦,并且可能会造成未知的 bug,除了上述的方案其实还有其他的方法但是基本原理都差不多,基本都是缓存和组件隐藏显示,在使用的使用应当根据自己的实际业务选择适合自己的方案。

以上就是Vue实现页面返回停留原位置的多种方案的详细内容,更多关于Vue页面返回停留原位置的资料请关注脚本之家其它相关文章!

相关文章

  • 详解如何使用router-link对象方式传递参数?

    详解如何使用router-link对象方式传递参数?

    这篇文章主要介绍了如何使用router-link对象方式传递参数,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-05-05
  • vue element实现表格增加删除修改数据

    vue element实现表格增加删除修改数据

    这篇文章主要为大家详细介绍了vue element实现表格增加删除修改数据,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-05-05
  • vue props传值失败 输出undefined的解决方法

    vue props传值失败 输出undefined的解决方法

    今天小编就为大家分享一篇vue props传值失败 输出undefined的解决方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-09-09
  • vue中实现在外部调用methods的方法(推荐)

    vue中实现在外部调用methods的方法(推荐)

    下面小编就为大家分享一篇vue中实现在外部调用methods的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-02-02
  • 详解在vue开发中如何利用.env文件

    详解在vue开发中如何利用.env文件

    我们在 vue 项目的目录中经常看到 env 开头的文件,在文件内声明一些变量,这些变量就是一些配置变量,在不同环境下可使用的变量,本文我们将给大家介绍在vue开发中如何利用.env文件,需要的朋友可以参考下
    2023-10-10
  • Vue组件tree实现树形菜单

    Vue组件tree实现树形菜单

    这篇文章主要为大家详细介绍了Vue组件tree实现树形菜单,小巧实用,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-04-04
  • Vue3计算属性和异步计算属性方式

    Vue3计算属性和异步计算属性方式

    这篇文章主要介绍了Vue3计算属性和异步计算属性方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-09-09
  • Vue3+TS+Vant3+Pinia(H5端)配置教程详解

    Vue3+TS+Vant3+Pinia(H5端)配置教程详解

    这篇文章主要介绍了Vue3+TS+Vant3+Pinia(H5端)配置教程详解,需要的朋友可以参考下
    2023-01-01
  • Vue监听iframe加载失败事件的三种实现方法

    Vue监听iframe加载失败事件的三种实现方法

    iframe 是一个 HTML 标签,作用是文档中的文档,或者浮动的框架(frame),iframe 元素会创建包含另外一个文档的内联框架(即行内框架),本文给大家介绍了Vue监听iframe加载失败事件的几种实现方法,需要的朋友可以参考下
    2025-06-06
  • 解决vue 格式化银行卡(信用卡)每4位一个符号隔断的问题

    解决vue 格式化银行卡(信用卡)每4位一个符号隔断的问题

    这篇文章主要介绍了vue 格式化银行卡(信用卡)每4位一个符号隔断的问题,本文给大家分享了解决方法,需要的朋友可以参考下
    2018-09-09

最新评论