vue单页应用中 返回列表记住上次滚动位置、keep-alive缓存之后更新列表数据 那点事
栏目: JavaScript · 发布时间: 7年前
内容简介:首先注意:思路很简章,在路由元信息中设置一个变量:scrollToTop,即标记是否要回到顶部,而我们的产品页面当离开路由的时候,还是判断这个变量是否为false,是则记录滚动的高度到vuex中 (所以我们这个变量有2个作用,你要维护2个也可以)
实践场景需求
- 产品列表中,滚动到一定位置的时候,点击查看产品信息,后退之后,需要回到原先的滚动位置,这是常见的需求
- 所有页面均在router-view中,暂时使用了keep-alive来缓存所有页面,所以进入不同分类的产品列表,和不同的产品详情页面,需要更新数据
首先注意:
- 本次实践测试环境为pc端的webkit内核浏览器,手机暂时不测试
- 使用$router.back(-1) 和浏览器后退按钮效果一样
- 必须使用keep-alive缓存路由页面才能记住上次的位置,否则使用浏览器后退或$router.back后退都会重新加载数据,使原来的内容高度改变
- 使用keep-alive之后,路由页面才能使用activated事件
记录上次列表滚动的高度位置,后退时恢复
思路很简章,在路由元信息中设置一个变量:scrollToTop,即标记是否要回到顶部,而我们的产品页面 productList 是要恢复上次滚动高度的,不回到顶部,所以设置为false
当离开路由的时候,还是判断这个变量是否为false,是则记录滚动的高度到vuex中 (所以我们这个变量有2个作用,你要维护2个也可以)
然后每当进入路由页面的时候,如果本路由的scrollToTop为false,则从vuex中读取上次记录的高度,并恢复
首先要注意一点,vue单页应用,切换路由时,滚动高度不会变,因为切换路由时只是切换了页面的内容,与滚动高度
当你在某路由页面的时候,滚动了100像素,然后切换了新的路由页面(改变了页面中的内容),只要新的路由页也可以滚动出100像素, 后退时,滚动高度不变, 这可以说是"BUG"
所以下面代码我们默认把 scrollToTop为true的设置滚动高度为0
我路由中的配置:
routes: [{
path: '/',
name: 'home',
component: Home,
meta: { title: "凤凰旅游" ,scrollToTop:true}
},
{
path: '/product',
name: 'product',
component: () => import('./views/Product.vue'),
meta: { title: "旅游" ,scrollToTop:true}
},
{
path: '/productList/:id',
name: 'productList',
component: () => import('./views/productList.vue'),
meta: { title: "列表" ,scrollToTop:false}
},
{
path: '/productShow/:id',
name: 'productShow',
component: () => import('./views/productShow.vue'),
meta: { title: "旅游产品显示" ,scrollToTop:true}
}
]复制代码
接下来在store.js中,维护一个变量用于记录
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
scrollTop :0
},
mutations: {
recordScrollTop(state,n){
state.scrollTop = n
}
},
actions: {
}
})复制代码
在main.js中的相关路由事件里
router.beforeEach(function(to,from,next){
document.title = to.meta.title
// 要离开页面如果设置为不滚回到顶部,则本页是要记住上滚动高度到vuex中,以便下次进来恢复高度
if(from.meta.scrollToTop==false) {
store.commit('recordScrollTop', document.documentElement.scrollTop)
}
next()
})
router.afterEach((to, from) => {
// 如果进入后的页面是要滚动到顶部,则设置scrollTop = 0
//否则从vuex中读取上次离开本页面记住的高度,恢复它
if(to.meta.scrollToTop==true){
setTimeout(()=>{
document.documentElement.scrollTop = 0
},10)
}else{
setTimeout(()=>{
document.documentElement.scrollTop = store.state.scrollTop
},50)
}
});复制代码
/* * 读取上次记录的滚动高度并且设置,必须放在router.afterEach里面 * 由于缓存了产品列表页面,每次进入会判断如果进入的是否为新的类别,则清空数据再重新加载数据,这时想设置scrollTop就无效,应该是视图渲染更新是异步的原因 * 看官方文档说调用afterEach之后,才触发 DOM 更新 * 所以afterEach里面的有涉及到DOM的操作,放在setTimeout里面,否则我试出了乱子.. */复制代码
使用了keep-alive缓存了页面之后,当参数不同的时候,更新数据
当进入不同分类的产品列表页面,或不同id的产品页面,由于缓存了上次的结果,当然要我们来处理更新
首先上面有说到,使用了keep-alive,路由页面便可以使用activated事件,因为使用了keep-alive其它普通的生命周期只执行了一次,而activated每次显示页面都会激活(类似小程序的onShow),必须使用这个来更新
思路:在页面data中维护一个id,默认为0 ,每次进这个页面时调用activated事件,在事件时面,判断这个id是否与路由url中的参数一致
如果不一致,则根据这个id更新相关数据,并且 把data中的id,更新为新的id ,别忘了还要清空上次分类的产品数据
当然别忘了,你应该初始读取一次数据,比如在created里面, 而activated第一次创建页面时不会激活,缓存之后,第二次进入才会开始激活(我想应该是如此。。)
上代码:
activated(){
//由于缓存了本页面,每次激活页面都要判断是否重置相关参数,并重新加载数据
if(this.id !== this.$route.params.id){this.id = this.$route.params.id //更新分类id
this.curpage = 1 //初始化页面为1
this.product = [] //清空上次不同分类的产品数据
this.getProduct('/api/productList.php',this.id,this.curpage).then((res)=>{
this.ptotal = res.total
res.products.forEach((item)=>{
this.product.push (item)
})
this.loading = false
})
}
}复制代码
如果更新或更正再补充。
以上所述就是小编给大家介绍的《vue单页应用中 返回列表记住上次滚动位置、keep-alive缓存之后更新列表数据 那点事》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- React通过redux缓存列表数据以及滑动位置,回退时恢复页面状态
- C#列表到列表转换
- Python笔记(二):列表+列表数据处理+函数
- python创建列表和向列表添加元素方法
- 在Bootstrap开发框架中使用bootstrapTable表格插件和jstree树形列表插件时候,对树列表条件和查询...
- Python 列表(List)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Web Security Testing Cookbook
Paco Hope、Ben Walther / O'Reilly Media / 2008-10-24 / USD 39.99
Among the tests you perform on web applications, security testing is perhaps the most important, yet it's often the most neglected. The recipes in the Web Security Testing Cookbook demonstrate how dev......一起来看看 《Web Security Testing Cookbook》 这本书的介绍吧!