vue中记录页面的滚动距离

本文介绍两种方法实现在Vue.js应用中从pageOne页面跳转到pageTwo页面时记录并恢复滚动位置,同时根据来源决定是否刷新数据。一种方法是使用Vue的keep-alive组件缓存页面状态;另一种则通过路由元信息存储滚动位置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

业务需求:pageOne页面是一个商品列表页面,在这个页面点击商品,就会跳转到pageTwo商品详细页面。此时再从pageTwo页面返回到pageOne页面时,pageOne页面需要做到:1.记录pageOne之前的滚动的距离。2.不重新请求数据。而从其它页面进入到pageOne页面时,pageOne页面不需要记录之前的滚动距离和需要重新请求数据。

1.使用keep-alive组件的实现方法

App.vue

<template>
  <div id="app">
    <div id="nav">
      <router-link to="/other">other</router-link> |
      <router-link to="/page-one">page-one</router-link> |
      <router-link to="/page-two">page-two</router-link>
    </div>
    <div class="container">
      <!-- 使用keep-alive是为了缓存page-one组件内部scroll的值 -->
      <keep-alive>
        <router-view/>
      </keep-alive>
    </div>
  </div>
</template>

page-one.vue

<template>
  <div class="page-one" ref="pageOneContainer">
    <p v-for="item in 20" :key="item">测试</p>
  </div>
</template>
<script>
export default {
  name: '',
  data () {
    return {
      scroll: 0
    }
  },
  beforeRouteEnter (to, from, next) {
    if (from.name === 'pageTwo') {
      next(vm => {
        const pageOneContainer = vm.$refs.pageOneContainer
        // 记录滚动高度
        pageOneContainer.scrollTop = vm.scroll
        // 不重新请求数据
        vm.notFetchData()
      })
    } else {
      next(vm => {
        const pageOneContainer = vm.$refs.pageOneContainer
        // 不记录滚动高度
        pageOneContainer.scrollTop = 0
        // 重新请求数据
        vm.fetchData()
      })
    }
  },
  beforeRouteLeave (to, from, next) {
    if (to.name === 'pageTwo') {
      const pageOneContainer = this.$refs.pageOneContainer
      this.scroll = pageOneContainer.scrollTop
    }
    next()
  },
  methods: {
    fetchData () {
      console.log('need flash')
    },
    notFetchData () {
      console.log('do not need flash')
    }
  }
}
</script>
<style scoped>
  .page-one {
    height: 100px;
    background-color: #ccc;
    overflow: auto;
  }
</style>

2.不使用keep-alive组件的实现方法

App.vue

<template>
  <div id="app">
    <div id="nav">
      <router-link to="/other">other</router-link> |
      <router-link to="/page-one">page-one</router-link> |
      <router-link to="/page-two">page-two</router-link>
    </div>
    <div class="container">
      <router-view/>
    </div>
  </div>
</template>

page-one.vue

<template>
  <div class="page-one" ref="pageOneContainer">
    <p v-for="item in 20" :key="item">测试</p>
  </div>
</template>
<script>
export default {
  name: '',
  beforeRouteEnter (to, from, next) {
    if (from.name === 'pageTwo') {
      next(vm => {
        const pageOneContainer = vm.$refs.pageOneContainer
        // 记录滚动高度
        pageOneContainer.scrollTop = vm.$route.meta.scroll || 0 // 从page-one路由的meta属性中获取scroll
        // 不重新请求数据
        vm.notFetchData()
      })
    } else {
      next(vm => {
        const pageOneContainer = vm.$refs.pageOneContainer
        // 不记录滚动高度
        pageOneContainer.scrollTop = 0
        // 重新请求数据
        vm.fetchData()
      })
    }
  },
  beforeRouteLeave (to, from, next) {
    if (to.name === 'pageTwo') {
      const pageOneContainer = this.$refs.pageOneContainer
      // 将page-one页面的scroll记录到路由的meta中
      this.$route.meta.scroll = pageOneContainer.scrollTop
    }
    next()
  },
  methods: {
    fetchData () {
      console.log('need flash')
    },
    notFetchData () {
      console.log('do not need flash')
    }
  }
}
</script>
<style scoped>
  .page-one {
    height: 100px;
    background-color: #ccc;
    overflow: auto;
  }
</style>

 效果展示:

使用keep-alive缓存组件只是为了保存page-one组件中的scroll属性,若不想缓存组件,可以有很多钟方法来记录scroll,例如上面使用的路由元信息meta、vuex、cookie、sessionStorage、localStorage等都能实现同样的效果。

 

转载于:https://www.cnblogs.com/luyuefeng/p/11401260.html

### Vue 中检测页面是否发生滚动的方法 在 Vue 应用程序中,可以利用 JavaScript 的 `scroll` 事件监听器来检测页面是否发生了滚动行为。具体来说,在组件的生命周期钩子内添加此事件监听器能够有效捕捉用户的滚动操作。 为了确保最佳实践并遵循现代前端开发模式,推荐使用组合式 API 或选项式 API 来管理这些逻辑。下面是一个基于选项式 API 实现的例子: ```javascript export default { data() { return { isScrolling: false, oldScrollTop: 0, // 记录上一次滚动位置 }; }, mounted() { window.addEventListener('scroll', handleScroll); }, beforeDestroy() { window.removeEventListener('scroll', handleScroll); }, methods: { handleScroll(event) { const scrollTop = document.documentElement.scrollTop || document.body.scrollTop; if (scrollTop !== this.oldScrollTop) { this.isScrolling = true; // 表明正在滚动 console.log("页面已开始滚动"); this.oldScrollTop = scrollTop; setTimeout(() => { this.isScrolling = false; // 设置短暂延迟后认为停止滚动 console.log("页面已经停止滚动"); }, 150); // 可调整这个时间间隔以适应不同需求 } } } } ``` 上述代码片段展示了如何定义一个名为 `handleScroll` 的方法用于处理滚动事件,并将其绑定到全局窗口对象上的 `scroll` 事件。每当用户触发滚动动作时都会调用该函数,进而更新数据属性 `isScrolling` 和记录当前滚动距离 `oldScrollTop`。此外还设置了定时器以便于区分连续滚动与静止状态之间的转换[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值