vue中记录页面的滚动距离

业务需求: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等都能实现同样的效果。

 

posted @ 2019-08-23 17:06  code-luyf  阅读(5594)  评论(0编辑  收藏  举报