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