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