Vue中keep-alive 实现后退不刷新并保持滚动位置


Posted in Javascript onMarch 17, 2020

什么是KeepAlive?

首先,我们要明确我们谈的是TCP的 KeepAlive 还是HTTP的 Keep-Alive。TCP的KeepAlive和HTTP的Keep-Alive是完全不同的概念,不能混为一谈。实际上HTTP的KeepAlive写法是Keep-Alive,跟TCP的KeepAlive写法上也有不同。

  • TCP的keepalive是侧重在保持客户端和服务端的连接,一方会不定期发送心跳包给另一方,当一方端掉的时候,没有断掉的定时发送几次心跳包,如果间隔发送几次,对方都返回的是RST,而不是ACK,那么就释放当前链接。设想一下,如果tcp层没有keepalive的机制,一旦一方断开连接却没有发送FIN给另外一方的话,那么另外一方会一直以为这个连接还是存活的,几天,几月。那么这对服务器资源的影响是很大的。
  • HTTP的keep-alive一般我们都会带上中间的横杠,普通的http连接是客户端连接上服务端,然后结束请求后,由客户端或者服务端进行http连接的关闭。下次再发送请求的时候,客户端再发起一个连接,传送数据,关闭连接。这么个流程反复。但是一旦客户端发送connection:keep-alive头给服务端,且服务端也接受这个keep-alive的话,两边对上暗号,这个连接就可以复用了,一个http处理完之后,另外一个http数据直接从这个连接走了。减少新建和断开TCP连接的消耗。

二者的作用简单来说:

HTTP协议的Keep-Alive意图在于短时间内连接复用,希望可以短时间内在同一个连接上进行多次请求/响应。

TCP的KeepAlive机制意图在于保活、心跳,检测连接错误。当一个TCP连接两端长时间没有数据传输时(通常默认配置是2小时),发送keepalive探针,探测链接是否存活。

总之,记住HTTP的Keep-Alive和TCP的KeepAlive不是一回事。

tcp的keepalive是在ESTABLISH状态的时候,双方如何检测连接的可用行。而http的keep-alive说的是如何避免进行重复的TCP三次握手和四次挥手的环节。

正文开始。

vue可以通过<keep-alive>元素包裹组件,实现缓存,下次使用时不需要重新创建该组件。但存在一个问题:keep-alive包裹的组件中有滚动元素时,keep-alive不会储存滚动位置。

实现后退不刷新主要依据keep-alive组件的activated和deactivated这两个生命周期钩子函数。

vue钩子函数的执行顺序:

不使用keep-alive

beforeRouteEnter --> created --> mounted --> destroyed

使用keep-alive

初次进入页面,beforeRouteEnter --> created --> mounted --> activated --> deactivated

再次进入缓存的页面,只会触发beforeRouteEnter -->activated --> deactivated。created和mounted不会再执行。

其中,

activated在keep-alive组件激活时调用.

deactivated在keep-alive组件被停用时调用.

Demo 实现了后退不刷新,并且返回时滚动到上次浏览的深度。

该demo中,包含三个链接导航。

home --> pageA --> pageB --> pageC

依次前进,每次前进到一个新页面都需要获取数据,而按下后退键后,

从pageC返回到pageB,pageB不再获取新数据,而是使用之前缓存的数据。

从pageB返回到pageA时,pageA不再获取新数据,而是使用之前的数据。并且当pageA存在滚动条时,返回时会滚动到上次浏览高度。

所以,pageA和pageB需要缓存,pageC不需要缓存。

//router.js
import Vue from 'vue';
import Router from 'vue-router';
Vue.use(Router);

const router = new Router({
 mode: 'hash',
 routes: [
 {
  path: '/',
  name: 'home',
  component: () =>
  import('./views/Home.vue'),
  meta: {
  title: '首页',
  keepAlive: false //此组件不需要被缓存
  }
 },
 {
  path: '/pageA',
  name: 'pageA',
  component: () =>
   import('./views/pageA.vue'),
  meta: {
  title: 'pageA',
  keepAlive: true,
  isBack: false
  }
 },
 {
  path: '/pageB',
  name: 'pageB',
  component: () =>
   import('./views/pageB.vue'),
  meta: {
  title: 'pageB',
  keepAlive: true,
  isBack: false
  }
 },
 {
  path: '/pageC',
  name: 'pageC',
  component: () =>
   import('./views/pageC.vue'),
  meta: {
  title: 'pageC',
  keepAlive: false
  }
 }
 ]
});
export default router;
//pageA.vue
<template>
 <div class="page-a">
  <h1>pageA</h1>
  <div>
   <div class="item" v-for="item in items" @click="goPageB">
    {{ item }}
   </div>
  </div>
  <h1 @click="goPageB">go pageB</h1>
 </div>
</template>

<script>
 export default {
  name: 'PageA',
  data() {
   return {
    msg: "我是PageA页面",
    items: Array.from({length:50}, (v,k) => k),
    data: "",
    scrollTop: 0
   };
  },
  beforeRouteEnter(to, from, next) {
   if(from.name == 'pageB'){
    to.meta.isBack = true;
   }

   next();
  },
  mounted() {
   console.log('mounted....');
   // this指向组件的实例,$el指向当前组件的DOM元素
   const $el = this.$el;
   //滚动事件
   $el.addEventListener("scroll", () => {
    //记录位置
    this.scrollTop = $el.scrollTop;
   });
  },
  activated() {
   if(!this.$route.meta.isBack){
    // 如果isBack是false,表明需要获取新数据,否则就不再请求,直接使用缓存的数据
    this.getData();
   } else {
    //恢复滚动条高度
    if(this.scrollTop) {
     setTimeout(() => {
      this.$el.scrollTop = this.scrollTop;
     }, 100);
    }
   }
   // 恢复成默认的false,避免isBack一直是true
   this.$route.meta.isBack = false;

  },
  methods: {
   getData() {
    // getData方法,模拟从后台请求数据
    this.data = "数据";
    console.log('get data')
   },
   goPageB(){
    this.$router.push({ path: "/pageB" });
   },
   back() {
    this.$router.push({ path: "/" });
   }
  },
 }
</script>
<style>
 .page-a {
  height: 100vh;
  overflow-y: auto;
 }
 .item {
  margin: 5px;
  padding: 10px;
  background: #ccc;
 }
</style>

代码请参考 链接 ;

后退不刷新还可以通过include实现,可参考链接

总结

到此这篇关于Vue中keep-alive 实现后退不刷新并保持滚动位置的文章就介绍到这了,更多相关keep-alive 后退不刷新持滚动位置内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
在textarea中屏蔽js的某个function的javascript代码
Apr 20 Javascript
jQuery实现点击后标记当前菜单位置(背景高亮菜单)效果
Aug 22 Javascript
初识angular框架后的所思所想
Feb 19 Javascript
jquery过滤特殊字符',防sql注入的实现方法
Aug 17 Javascript
jquery实现表单获取短信验证码代码
Mar 13 Javascript
Angularjs中ng-repeat的简单实例
Aug 25 Javascript
vue中v-model动态生成的实例详解
Oct 27 Javascript
js循环map 获取所有的key和value的实现代码(json)
May 09 Javascript
小程序云开发实战小结
Oct 25 Javascript
vue-element-admin 菜单标签失效的解决方式
Nov 12 Javascript
vue中的使用token的方法示例
Mar 10 Javascript
Jquery+AJAX实现无刷新上传并重命名文件操作示例【PHP后台接收】
May 29 jQuery
用js编写留言板
Mar 17 #Javascript
Vue脚手架编写试卷页面功能
Mar 17 #Javascript
基于JavaScript实现留言板功能
Mar 16 #Javascript
JS实现简易留言板(节点操作)
Mar 16 #Javascript
JavaScript实现旋转木马轮播图
Mar 16 #Javascript
基于JavaScript实现贪吃蛇游戏
Mar 16 #Javascript
原生js实现的金山打字小游戏(实例代码详解)
Mar 16 #Javascript
You might like
PHP数组无限分级数据的层级化处理代码
2012/12/29 PHP
Thinkphp搭建包括JS多语言的多语言项目实现方法
2014/11/24 PHP
Zend Framework入门之环境配置及第一个Hello World示例(附demo源码下载)
2016/03/21 PHP
Yii实现文章列表置顶功能示例
2016/10/18 PHP
PHP对称加密算法(DES/AES)类的实现代码
2017/11/14 PHP
PDO::commit讲解
2019/01/27 PHP
MooTools 1.2中的Drag.Move来实现拖放
2009/09/15 Javascript
JavaScript 学习笔记二 字符串拼接
2010/03/28 Javascript
js中scrollHeight,scrollWidth,scrollLeft,scrolltop等差别介绍
2012/05/16 Javascript
点击弹出层效果&amp;弹出窗口后网页背景变暗效果的实现代码
2014/02/10 Javascript
js动态创建标签示例代码
2014/06/09 Javascript
nodejs教程之异步I/O
2014/11/21 NodeJs
JavaScript将base64图片转换成formData并通过AJAX提交的实现方法
2016/10/24 Javascript
headjs实现网站并行加载但顺序执行JS
2016/11/29 Javascript
如何防止INPUT按回车自动提交表单FORM
2016/12/06 Javascript
JavaScript定义函数_动力节点Java学院整理
2017/06/27 Javascript
JavaScript创建对象的七种方式全面总结
2017/08/21 Javascript
Vue2.0权限树组件实现代码
2017/08/29 Javascript
vue2 全局变量的设置方法
2018/03/09 Javascript
JS简单实现查看文档创建日期、修改日期和文档大小的方法示例
2018/04/08 Javascript
vue.js数据绑定操作详解
2018/04/23 Javascript
小程序点餐界面添加购物车左右摆动动画
2020/09/23 Javascript
利用vue3+ts实现管理后台(增删改查)
2020/10/30 Javascript
vue项目中使用rem,在入口文件添加内容操作
2020/11/11 Javascript
[02:34]DOTA2亚洲邀请赛 BG战队出场宣传片
2015/03/09 DOTA
[02:28]DOTA2 2017国际邀请赛小组赛回顾
2017/08/09 DOTA
Python3对称加密算法AES、DES3实例详解
2018/12/06 Python
python判断一个变量是否已经设置的方法
2020/08/13 Python
为中国消费者甄选天下优品:网易严选
2016/08/11 全球购物
美国休闲服装品牌:Express
2016/09/24 全球购物
AOP的定义以及作用
2013/09/08 面试题
软件测试工程师面试问题精选
2016/10/28 面试题
财务会计专业应届毕业生求职信
2013/10/18 职场文书
简单的大学生自我鉴定
2014/02/18 职场文书
读书之星事迹材料
2014/05/12 职场文书
微信小程序结合ThinkPHP5授权登陆后获取手机号
2021/11/23 PHP