vue单页应用中 返回列表记住上次滚动位置、keep-alive缓存之后更新列表数据 那点事
实践场景需求
- 产品列表中,滚动到一定位置的时候,点击查看产品信息,后退之后,需要回到原先的滚动位置,这是常见的需求
- 所有页面均在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 =
},)
}else{
setTimeout(()=>{
document.documentElement.scrollTop = store.state.scrollTop
},)
}
});
/*
* 读取上次记录的滚动高度并且设置,必须放在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缓存之后更新列表数据 那点事的更多相关文章
- 如何在vue单页应用中使用百度地图
作为一名开发人员,每次接到开发任务,我们首先应该先分析需求,然后再思考技术方案和解决方案.三思而后行,这是一个好的习惯. 需求:本项目是采用vue组件化开发的单页应用项目,现需要在项目中引入百度的地图 ...
- vue 单页应用中微信支付的坑
vue 单页应用中微信支付的坑 标签(空格分隔): 微信 支付 坑 vue 场景 在微信H5页面(使用 vue-router2 控制路由的 vue2 单页应用项目)中使用微信 jssdk 进行微信支付 ...
- vue单页应用中根据不同城市不同业务添加百度统计代码
问题描述: 我们知道一般的百度统计代码是添加在html的head里的:但是,因为目前项目是用vue开发的单页应用,所以在路由跳转之间不会刷新页面, 统计代码如果放在项目里的index.heml的hea ...
- vue 路由跳转记住滚动位置,返回时回到上次滚动位置
参考:https://blog.csdn.net/qq_40204835/article/details/79853685 方法一: 利用Keep-Alive和监听器 1.首先在路由中引入需要的模块 ...
- vue单页应用中,使用setInterval()定时向服务器获取数据,后来跳转页面后,发现还在不停的获取数据。
使用VUE开发单页项目时遇到这样的问题,mounted中使用setInterval()定时向服务器获取数据,后来跳转页面后,发现还在不停的获取数据.我以为是因为我路由用的push导致的,改成repla ...
- vue单页应用前进刷新后退不刷新方案探讨
引言 前端webapp应用为了追求类似于native模式的细致体验,总是在不断的在向native的体验靠拢:比如本文即将要说到的功能,native由于是多页应用,新页面可以启用一个的新的webview ...
- 解决vue单页路由跳转后scrollTop的问题
作为vue的初级使用者,在开发过程中遇到的坑太多了.在看页面的时候发现了页面滚动的问题,当一个页面滚动了,点击页面上的路由调到下一个页面时,跳转后的页面也是滚动的,滚动条并不是在页面的顶部 在我们写路 ...
- 基于vue单页应用的例子
代码地址如下:http://www.demodashi.com/demo/13374.html 目录结构 src目录 主要的代码目录 components 存放项目组件 router 路由文件 sto ...
- js中对arry数组的各种操作小结 瀑布流AJAX无刷新加载数据列表--当页面滚动到Id时再继续加载数据 web前端url传递值 js加密解密 HTML中让表单input等文本框为只读不可编辑的方法 js监听用户的键盘敲击事件,兼容各大主流浏览器 HTML特殊字符
js中对arry数组的各种操作小结 最近工作比较轻松,于是就花时间从头到尾的对js进行了详细的学习和复习,在看书的过程中,发现自己平时在做项目的过程中有很多地方想得不过全面,写的不够合理,所以说啊 ...
随机推荐
- dfs和bfs(链式前向星实现)
dfs代码: #include<iostream>#include<Algorithm>#include<cstring>#include<cstdio> ...
- 普通javabean 获得项目的绝对路径
方式一:String path = RequestContext.class.getResource("/").getFile();
- (C++)关于i++和i++的左值、右值问题
1.什么是左值和右值? 左值就是出现在表达式左边的值(等号左边),可以被改变,他是存储数据值的那块内存的地址,也称为变量的地址: 右值是指存储在某内存地址中的数据,也称为变量的数据. 左值可以作为右值 ...
- 面向对象基础及UML建模语言
1.面向对象的方法起源于面向对象程序设计语言,其发展过程大体经历了初始阶段.发展阶段和成熟阶段. 2.面向对象方法主要优点 (1)从认识论的角度可以看出,面向对象方法改变了开发软件的方式. (2)面向 ...
- BZOJ1415[Noi2005]聪聪和可可——记忆化搜索+期望dp
题目描述 输入 数据的第1行为两个整数N和E,以空格分隔,分别表示森林中的景点数和连接相邻景点的路的条数. 第2行包含两个整数C和M,以空格分隔,分别表示初始时聪聪和可可所在的景点的编号. 接下来E行 ...
- Uva10474-STL水题-白书
白书的一道水题.话说好久没认真做难题了.今天出了排名,所有队伍里倒数第一啊! 代码没什么可说的了. #include <algorithm> #include <cstring> ...
- 洛谷P1516 青蛙的约会(扩展欧几里德)
洛谷题目传送门 很容易想到,如果他们相遇,他们初始的位置坐标之差\(x-y\)和跳的距离\((n-m)t\)(设\(t\)为跳的次数)之差应该是模纬线长\(l\)同余的,即\((n-m)t\equiv ...
- Android Service服务的生命周期
与activity类似,服务也存在生命周期回调方法,你可以实现这些方法来监控服务的状态变化,并在适当的时机执行一些操作. 以下代码提纲展示了服务的每个生命周期回调方法: public class Ex ...
- Java核心技术-映射
集是一个集合,它可以快速地查找现有的元素.但是,要查看一个元素,需要有要查找元素的精确副本.这不是一种非常通用的查找方式.通常,我们知道某些键的信息,并想要查找与之对应的元素.映射(map)数据结构就 ...
- AtCoder Regular Contest 066 F Contest with Drinks Hard
题意: 你现在有n个题目可以做,第i个题目需要的时间为t[i],你要选择其中的若干题目去做.不妨令choose[i]表示第i个题目做不做.定义cost=∑(i<=n)∑(i<=j<= ...