Vue中记录页面的滚动距离

282 阅读1分钟

业务需求: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

}

},

`

activated(){

this.$refs.pageOneContainer.scrollTop = this.scroll

},

`

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

}else {

    this.scroll = 0

    }

next()

},

methods: {

fetchData () {

console.log(````'重新请求数据'``)`


`},`

`notFetchData () {`

`console.log(````'不重新请求数据`'``)`  

}

}

}

</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: ''``,

mounted(){

this.refs.pageOneContainer.scrollTop=this.refs.pageOneContainer.scrollTop = this.route.meta.scroll

},

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

}else{

const pageOneContainer = this.$refs.pageOneContainer

// 将page-one页面的scroll记录到路由的meta中

this.$route.meta.scroll = 0

}

next()

},

methods: {

fetchData () {

console.log(``'重新请求数据'``)

},

notFetchData () {

console.log(``'不重新请求数据'``)

}

}

}

</script>

<style scoped>

.page-one {

height: 100px;

background-color: #ccc;

overflow: auto;

}

</style>

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