什么是keep-alive

有时候我们不希望组件被重新渲染影响使用体验;

或者处于性能考虑,避免多次重复渲染降低性能。而是希望组件可以缓存下来,维持当前的状态。这时候就需要用到keep-alive组件。 官网释义:

<keep-alive> 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。和 <transition> 相似,<keep-alive> 是一个抽象组件:它自身不会渲染一个 DOM 元素,也不会出现在父组件链中。

当组件在 <keep-alive> 内被切换,它的 activated 和 deactivated 这两个生命周期钩子函数将会被对应执行。

在 2.2.0 及其更高版本中,activated 和 deactivated 将会在 <keep-alive> 树内的所有嵌套组件中触发。

主要用于保留组件状态或避免重新渲染。

应用场景

如果未使用keep-alive组件,则在页面回退时仍然会重新渲染页面,触发created钩子,使用体验不好。 在以下场景中使用keep-alive组件会显著提高用户体验:

  1. 商品列表页点击商品跳转到商品详情,返回后仍显示原有信息
  2. 订单列表跳转到订单详情,返回,等等场景。

keep-alive的生命周期

  • 初次进入时:
    1. created > mounted > activated
    2. 退出后触发 deactivated
  • 再次进入:
    1. 只会触发 activated
  • 事件挂载的方法等,只执行一次的放在 mounted 中;组件每次进去执行的方法放在 activated

在项目中使用

一、更改App.vue

<div id="app" class='wrapper'>
<keep-alive>
<!-- 需要缓存的视图组件 -->
<router-view v-if="$route.meta.keepAlive">
</router-view>
</keep-alive> <!-- 不需要缓存的视图组件 -->
<router-view v-if="!$route.meta.keepAlive">
</router-view>
</div>

二、在路由中设置keepAlive

{
path: 'list',
name: 'itemList', // 商品管理
component (resolve) {
require(['@/pages/item/list'], resolve)
},
meta: {
keepAlive: true,
title: '商品管理'
}
}

三、更改 beforeEach钩子

这一步是为了清空无用的页面缓存。 假设现在A、B两个页面都开启的缓存:

  • 若第一次进入A页面后退出,再次进入页面时,页面不会刷新。这和目前的业务逻辑不符。我们想要的结果是A页面前进后返回,页面保持不变,而不是退出后重新进入保持不变。
  • 在进入过A页面后进入B页面,经过测试后发现,B页面竟然会显示A页面的缓存,尽管url已经改变~

为了解决这个问题,需要判断页面是在前进还是后退。 在beforeEach钩子添加代码:

let toDepth = to.path.split('/').length
let fromDepth = from.path.split('/').length
if (toDepth < fromDepth) {
// console.log('后退。。。')
from.meta.keepAlive = false
to.meta.keepAlive = true
}

记录页面滚动位置

keep-alive并不会记录页面的滚动位置,所以我们在跳转时需要记录当前的滚动位置,在触发activated钩子时重新定位到原有位置。 具体设计思路:

  1. deactivated钩子中记录当前滚动位置,在这里我使用的是localStorage
 deactivated () {
window.localStorage.setItem(this.key, JSON.stringify({
listScrollTop: this.scrollTop
}))
}
  1. activated钩子中滚动:
this.cacheData = window.localStorage.getItem(this.key) ? JSON.parse(window.localStorage.getItem(this.key)) : null
$('.sidebar-item').scrollTop(this.cacheData.listScrollTop)

Vue 之keep-alive的使用,实现页面缓存的更多相关文章

  1. vue中keep-alive,include的指定页面缓存问题

    做vue项目时,有时要在某些页面做缓存,而其它页面不要.比如:A:首页,B:获取所有订单页面,C:订单详情页面:从A(首页)进入 B(获取所有订单)时应该不缓存,B(所有订单)进入 C(订单详情)订单 ...

  2. vue.js 作一个用户表添加页面----初级

    使用vue.js 制作一个用户表添加页面,实际上是把原来需要使用js写的部分,改写成vue.js的格式 首先,想象一下,先做思考,我们要添加用户表,设涉及到哪些数据,一个是用户id,一个是用户名,一个 ...

  3. 设置vue启动项目后默认显示的页面

    通过配置路由,可以设置vue项目启动后默认显示的页面.路由的path设置为path:"/",启动项目后就会显示默认的组件页面. import Vue from 'vue' impo ...

  4. vue路由跳转取消上个页面的请求和去掉重复请求

    vue路由跳转取消上个页面的请求和去掉重复请求 axios 的二次封装(拦截重复请求.异常统一处理) axios里面拦截重复请求

  5. vue 通过 name 和 params 进行调整页面传参刷新参数丢失问题&vue路由可选参数

    vue  通过 name 和 params 进行调整页面传参刷新参数丢失问题 router.js: export default new Router({ routes: [ { path: '/', ...

  6. VUE项目中使用this.$forceUpdate();解决页面v-for中修改item属性值后页面v-if不改变的问题

    VUE项目中使用this.$forceUpdate();解决页面v-for中修改item属性值后页面v-if不改变的问题:https://blog.csdn.net/jerrica/article/d ...

  7. vue路由传参并跳转页面

    在vue项目中参数的传递可以使用本地缓存或者Vuex,那么vue能不能像小程序一样路由传参呢,显然是可以的而且非常简单 方式一:query传参 //传参 go(){ that.$router.push ...

  8. Vue 实现动态路由及登录&404页面跳转控制&页面刷新空白解决方案

    Vue实现动态路由及登录&404页面跳转控制&页面刷新空白解决方案   by:授客 QQ:1033553122   开发环境   Win 10   Vue 2.9.6   node-v ...

  9. vue修改对象的属性值后页面不重新渲染

    原文地址:vue修改对象的属性值后页面不重新渲染 最近项目在使用vue,遇到几次修改了对象的属性后,页面并不重新渲染,场景如下: HTML页面如下: [html] view plain copy &l ...

随机推荐

  1. Python3使用Print输出彩色字体

    一.介绍 在一些开发程序中,有些输出消息需要突出显示,我们可以尝试着给他们换上更靓丽的颜色来突出显示. 二.实现过程 终端的字符颜色是用转义序列控制的,是文本模式下的系统显示功能,和具体的语言无关. ...

  2. PTA 银行排队问题之单队列多窗口服务 (25分)

    PTA 银行排队问题之单队列多窗口服务 (25分) 假设银行有K个窗口提供服务,窗口前设一条黄线,所有顾客按到达时间在黄线后排成一条长龙.当有窗口空闲时,下一位顾客即去该窗口处理事务.当有多个窗口可选 ...

  3. C# for Beginner Part 21 to 30

    Part 21 Inheritance in c# Why Inheritance Pillars(支架) of Object Oriented Programming 1,Inheritance(继 ...

  4. string类运用:特殊的翻译

    特殊的翻译 小明的工作是对一串英语字符进行特殊的翻译:当出现连续且相同的小写字母时,须替换成该字母的大写形式,在大写字母的后面紧跟该小写字母此次连续出现的个数:与此同时,把连续的小写字母串的左侧和右侧 ...

  5. 后台大哥请进一步:使用Visual Studio编译scss和souce map实现前后端的完美结合

    title: 后台大哥请进一步:使用Visual Studio编译scss和souce map实现前后端的完美结合 date: 2020-06-28 sidebarDepth: 2 tags: win ...

  6. 如何实现异步 connect

    写过网络程序的同学,应该都知道 connect 函数,在 socket 开始读写操作之前,先要进行连接,也即 TCP 的三次握手 , 这个过程就是在 connect 函数中完成的, connect 函 ...

  7. Scrapy入门到放弃05:让Item在Pipeline中飞一会儿

    前言 "又回到最初的起点,呆呆地站在镜子前". 本来这篇是打算写Spider中间件的,但是因为这一块涉及到Item,所以这篇文章先将Item讲完,顺便再讲讲Pipeline,然后再 ...

  8. java-TCP协议发送和接收数据

    TCP协议接收数据的步骤: A:创建接收数据的Socket对象 创建对象的时候要指定端口 B:监听客户端连接 等待客户端连接 C:获取Socket对象的输入流(字节流) D:读数据,并显示在控制台 E ...

  9. [atARC084F]XorShift

    如果异或变为加法和减法,那么根据扩欧,$k$合法当且仅当$k|\gcd_{i=1}^{n}a_{i}$ 换一种方式定义约数:$x$是$y$的约数当且仅当存在$p_{i}\in \{0,1\}$使得$\ ...

  10. [bzoj1106]立方体大作战

    先贪心,容易发现如果两个点中间没有点对,那么一定可以先把这两个点消掉分析一下,就可以发现这样两个点的答案就是这两个点对中间不成对的点数量扫描过去,线段树维护每一个点的权值(是否会被算入答案)即可 1 ...