業務需求: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等都能實現同樣的效果。
