Vue Router 返回后记住滚动条位置的实现方法

 更新时间:2023年09月07日 10:52:26   作者:悦爱克鲁伊夫  
使用 Vue router 创建 SPA(Single Page App),往往有这种需求:首页是列表页,点击列表项进入详情页,在详情页点击返回首页后,希望看到的是,首页不刷新,并且滚动条停留在之前的位置,这篇文章主要介绍了Vue Router 返回后记住滚动条位置的实现方法,需要的朋友可以参考下

使用 Vue router 创建 SPA(Single Page App),往往有这种需求:首页是列表页,点击列表项进入详情页,在详情页点击返回首页后,希望看到的是,首页不刷新,并且滚动条停留在之前的位置。

使用 Vue router 创建 SPA(Single Page App),往往有这种需求:首页是列表页,点击列表项进入详情页,在详情页点击返回首页后,希望看到的是,首页不刷新,并且滚动条停留在之前的位置。效果如图:

效果

这里涉及两个功能点:

  • route 返回后不刷新页面
  • route 返回后滚动条跳转到离开之前的位置

功能一:route 返回后不刷新页面

该功能比较常用,使用 keep-alive 即可。首先 keep-alive 包裹 router-view ,代码如下:

<keep-alive>
  <router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view>
</div>

然后,在 router.js 中,对不需要刷新的 route 项 meta.keepAlive 标记为 true,即可实现。代码如下:

export default new Router({
  ...
  routes: [
    {
      path: '/',
      name: 'home',
      component: Home,
      meta: {
        keepAlive: true // 需要缓存
      }
    },
    {
      path: '/about',
      name: 'about',
      component: () => import(/* webpackChunkName: "about" */ './views/About.vue'),
      meta: {
        keepAlive: false // 不需要缓存
      }
    }
  ]
  ...
})

功能二:route 返回后滚动条跳转到离开之前的位置

为了实现该功能,在网上查找,发现 scrollBehavior 出现最多,但经过测试,只能点击浏览器自带的返回按钮才有效,如点击自定义的按钮返回则失败。继续找,发现以下这种方法可以实现,分2步:

  • 获取并存储页面的 scrollTop value
  • 返回页面时取出并设置 scrollTop value

第一步: 获取并存储页面的 scrollTop value

首页组件,点击列表项 route 到详情页之前,先获取存储当前 scrollTop。查看 clickItem 方法,代码如下:

<template>
  <div class="wrapper">
    <ul class="list">
      <li v-for="item in dataList" @click="clickItem(item)">
        {{ item }}
      </li>
    </ul>
  </div>  
</template>
<script>
  export default {
    name: 'simple-scollbehavior',
    data() {
      return {
        dataList: [
          'Start', '(´・ω・`) ', '(/TДT)/ ', '>ㅂ<',
          'o(*≧▽≦)ツ', '(≖ ‿ ≖)✧', '(o^∇^o)ノ', ' (´・ω・)ノ',
          '(´・ω・`)', 'ヽ(・ω・。)ノ', '(`・ω・´)', '╰(*°▽°*)╯',
          '╮( ̄▽ ̄)╭', '( ̄▽ ̄)~*', '(⊙ˍ⊙)', '====',
          '(ง •̀_•́)ง', '(´・ω・`) ', '(/TДT)/ ', '>ㅂ<',
          '╮( ̄▽ ̄)╭', '( ̄▽ ̄)~*', '(⊙ˍ⊙)', 'End'
        ],
        keepScroll: 0 // 记录离开页面时的 scroll-positon 
      };
    },
    methods: {
      clickItem(item){
        const scrollTop = Math.max(window.pageYOffset, document.documentElement.scrollTop, document.body.scrollTop)
        this.keepScroll = scrollTop;
        this.$router.push('/about')
      }
    }
  };
</script>

第二步:返回页面时取出并设置 scrollTop value

由于首页设置了 keepAlive,页面不会刷新所以组件内的生命周期方法都不会执行,除了 activated 生命方法。官方说法当组件在 <keep-alive> 内被切换时,它的 activated 和 deactivated 这两个生命周期钩子函数将会被对应执行。

所以,将设置 scrollTop value 写在 activated 即可。但这里遇到一个坑,直接写无效,必须使用 setTimeOut 延迟执行才有效。具体原因,还有待解惑。代码如下:

<template>
...
</template>
<script>
  export default {
    name: 'simple-scollbehavior',
    ...
    //keep-alive 中组件激活 lifecircle-func
    //注意:必须 setTimeout 才能有效 scrollTop to body
    activated() {
      var gotoScroll = this.keepScroll
      setTimeout(function(){
          //兼容 PC and Mobile 写两个
          document.body.scrollTop = gotoScroll;
          document.documentElement.scrollTop = gotoScroll;
      }, 10);
    }
  };
</script>

完整代码如下:

<template>
  <div class="wrapper">
    <ul class="list">
      <li v-for="item in dataList" @click="clickItem(item)">
        {{ item }}
      </li>
    </ul>
  </div>  
</template>
<script>
  export default {
    name: 'simple-scollbehavior',
    data() {
      return {
        dataList: [
          'Start', '(´・ω・`) ', '(/TДT)/ ', '>ㅂ<',
          'o(*≧▽≦)ツ', '(≖ ‿ ≖)✧', '(o^∇^o)ノ', ' (´・ω・)ノ',
          '(´・ω・`)', 'ヽ(・ω・。)ノ', '(`・ω・´)', '╰(*°▽°*)╯',
          '╮( ̄▽ ̄)╭', '( ̄▽ ̄)~*', '(⊙ˍ⊙)', '====',
          '(ง •̀_•́)ง', '(´・ω・`) ', '(/TДT)/ ', '>ㅂ<',
          '╮( ̄▽ ̄)╭', '( ̄▽ ̄)~*', '(⊙ˍ⊙)', 'End'
        ],
        keepScroll: 0 // 记录离开页面时的 scroll-positon 
      };
    },
    methods: {
      loadmore(loaded) {
        setTimeout(() => {
          this.dataList = this.dataList.concat(this.dataList);
          loaded('done');
        }, 2000);
      },
      clickItem(item){
        const scrollTop = Math.max(window.pageYOffset, document.documentElement.scrollTop, document.body.scrollTop)
        this.keepScroll = scrollTop;
        this.$router.push('/about')
      }
    },
    //keep-alive 中组件激活 lifecircle-func
    //注意:必须 setTimeout 才能有效 scrollTop to body
    activated() {
      var gotoScroll = this.keepScroll
      setTimeout(function(){
          //兼容 PC and Mobile 写两个
          document.body.scrollTop = gotoScroll;
          document.documentElement.scrollTop = gotoScroll;
          console.debug('set:' + gotoScroll)
      }, 10);
    }
  };
</script>

到此这篇关于Vue Router 返回后记住滚动条位置的实现方法的文章就介绍到这了,更多相关vue返回记住滚动条位置内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 关于Element UI table 顺序拖动方式

    关于Element UI table 顺序拖动方式

    这篇文章主要介绍了关于Element UI table 顺序拖动方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-08-08
  • element-plus中如何实现按需导入与全局导入

    element-plus中如何实现按需导入与全局导入

    本文主要介绍了element-plus中如何实现按需导入与全局导入,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-11-11
  • Vue 实现前端权限控制的示例代码

    Vue 实现前端权限控制的示例代码

    这篇文章主要介绍了Vue 实现前端权限控制的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-07-07
  • vue可滑动的tab组件使用详解

    vue可滑动的tab组件使用详解

    这篇文章主要为大家详细介绍了vue可滑动的tab组件使用,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-07-07
  • Vue-resource安装过程及使用方法解析

    Vue-resource安装过程及使用方法解析

    这篇文章主要介绍了Vue-resource安装过程及使用方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-07-07
  • Vue路由钩子之afterEach beforeEach的区别详解

    Vue路由钩子之afterEach beforeEach的区别详解

    这篇文章主要介绍了Vue路由钩子 afterEach beforeEach区别 ,vue-router作为vue里面最基础的服务,学习一段时间,对遇到的需求进行一些总结。需要的朋友可以参考下
    2018-07-07
  • 详解如何在vue项目中使用lodop打印插件

    详解如何在vue项目中使用lodop打印插件

    这篇文章主要介绍了详解如何在vue项目中使用lodop打印插件,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-09-09
  • 详解Vue-Cli 异步加载数据的一些注意点

    详解Vue-Cli 异步加载数据的一些注意点

    本篇文章主要介绍了详解Vue-Cli 异步加载数据的一些注意点,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-08-08
  • Vue进阶之利用transition标签实现页面跳转动画

    Vue进阶之利用transition标签实现页面跳转动画

    这篇文章主要为大家详细介绍了Vue如何利用transition标签实现页面跳转动画,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起一下
    2023-08-08
  • Vue3中引用本地图片路径的方法详解

    Vue3中引用本地图片路径的方法详解

    这篇文章主要为大家详细介绍了Vue3中引用本地图片路径的常用方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-03-03

最新评论