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等都能實現同樣的效果。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM