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页面返回停留原位置的资料请关注脚本之家其它相关文章!

相关文章

  • element ui loading加载开启与关闭方式

    element ui loading加载开启与关闭方式

    这篇文章主要介绍了element ui loading加载开启与关闭方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-08-08
  • Vue3与pywebview实现获取本地文件夹的绝对路径

    Vue3与pywebview实现获取本地文件夹的绝对路径

    这篇文章主要为大家详细介绍了Vue3如何结合pywebview实现获取本地文件夹的绝对路径,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下
    2024-11-11
  • vue vant Area组件使用详解

    vue vant Area组件使用详解

    这篇文章主要介绍了vue vant Area组件使用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-12-12
  • Vuex中的State使用介绍

    Vuex中的State使用介绍

    今天小编就为大家分享一篇关于Vuex中的State使用介绍,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01
  • postcss-pxtorem设置不转换UI框架的CSS单位问题

    postcss-pxtorem设置不转换UI框架的CSS单位问题

    这篇文章主要介绍了postcss-pxtorem设置不转换UI框架的CSS单位问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-07-07
  • Vue+Echarts实现绘制多设备状态甘特图

    Vue+Echarts实现绘制多设备状态甘特图

    这篇文章主要为大家详细介绍了Vue如何结合Echarts实现绘制多设备状态甘特图,文中的示例代码讲解详细,有需要的小伙伴可以跟随小编一起学习一下
    2024-03-03
  • vite.config.ts如何加载.env环境变量

    vite.config.ts如何加载.env环境变量

    这篇文章主要介绍了vite.config.ts加载.env环境变量方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-10-10
  • 详解Vuejs2.0 如何利用proxyTable实现跨域请求

    详解Vuejs2.0 如何利用proxyTable实现跨域请求

    本篇文章主要介绍了Vuejs2.0 如何利用proxyTable实现跨域请求,具有一定的参考价值,有兴趣的可以了解一下
    2017-08-08
  • 基于Vue设计实现一个弹幕组件

    基于Vue设计实现一个弹幕组件

    这篇文章主要给大家分享一个开发中常见的需求,接下来将为大家详细介绍弹幕的实现以及设计思路一步一步描述出来,希望大家能够喜欢
    2023-06-06
  • vue 父组件中调用子组件函数的方法

    vue 父组件中调用子组件函数的方法

    这篇文章主要介绍了vue 父组件中调用子组件函数的方法,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值 ,需要的朋友可以参考下
    2019-06-06

最新评论