vue中的keep-alive

1 keep-alive业务场景使用

问题:
在k页面根据pageNum请求到该分页的数据进行展示,pageNum的值假设此时为3,去到a页面,点击匹配其他条件又到k页面,此时因为k页面被keep-alive保存状态,有数据缓存,所以显示的还是pageNum=3的分页数据造成页面显示异常;
试过把pageNum初始化为1的方法,但是当数据量过大时,会先显示数据异常的页面,然后才显示初始化为1的分页数据;
需求:
a→k→b→a→k即离开k页面后只要从a页面点击跳转到k页面时,不使用缓存数据,数据应该更新(要注意如果是原来的匹配条件时,缓存需要保存);
解决方法:
第一种(成功解决)
在a页面路由跳转需要携带的参数里添加添加一个初始化变量initial=true决定是否初始化;
在k页面的activated钩子里获取路由的参数,然后用一个变量接即initial2=initial || false
然后if(initial2) {
pageNum = 1 //初始化
}

k页面(即分情况刷新或缓存数据的页面)
a页面(点击a页面不同地方携带不同的参数请求不同的数据在k页面显示)

k页面

data() {
  return {
    initialization: true,
  }
}
async activated() {
    console.log("进入到activated");
    this.queryForm=this.$route.query;
    this.initialization=this.queryForm.initialization||false;
    console.log(this.totalQuantityProblem.initialization);
    if(this.initialization){
      console.log("数据初始化");
      this.page.pageNum = 1;
      this.totalQuantityProblem.type=this.queryForm.type||'';
      this.totalQuantityProblem.status=Number(this.queryForm.status);
      await this.getData();
      await this.getMinus();
    }
},

a页面

methods: {
    goProblemDetail(data) {
      this.$router.push({
        path: "/allProblemHome",
        query: {
          type:data.type,
          status:data.status||0,
          initialization:true,
        },
      })
    },
}

第二种(没被采用)
在路由种设置keepAlive属性结合在组件使用v-if判断是否需要缓存

{
  path: 'list',
  name: 'itemList',
  meta: {
    keepAlive: true,
    title: '列表页'
 }
}

因为项目组件太多业务逻辑复杂,最开始时没有使用这个控制是否缓存,所以该方法没采用。
第三种(比较复杂,没被采用—大概的思路)
用 keep-alive 提供的 include 和 exclude ,然后配合vuex实现动态控制。
app.vue

<keep-alive :include='includes' :exclude='':max="3">
  <router-view></router-view>
</keep-alive>

其中include代表着要缓存的,exclude代表着非缓存的,max代表最多缓存的个数。

// 获取vuex的数据
import {mapGetters} from 'vuex'
export default {
  computed: {// 在computed中动态监控
     ...mapGetters(['includes']),
   },
  methods: {
     changeStore() {
       // 改变vue的数据,在这用不到
       this.$store.commit('change', 'tableLists')
     }
   }
}

vuex

const keepalive = {
  state: {
    includes: ['tableLists']
  },
  mutations: {
    change(state, payload) {
      state.includes = payload
    },
  },
  getters: {
    includes(state) {
      return state.includes
    }
  }
};

export default keepalive

2 原理

参考文章:
keep-alive原理分析(有源码分析)

2.1 keep-alive是什么?

是vue中的内置组件,能在组件切换过程中将状态保留在内存中,防止重复渲染DOM;
包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们;
可以设置以下props属性:
● include - 字符串或正则表达式。只有名称匹配的组件会被缓存;
● exclude - 字符串或正则表达式。任何名称匹配的组件都不会被缓存;
● max - 数字。最多可以缓存多少组件实例
使用include和exclude的注意点:
● 每个组件内部添加 {name:xx}
● 若将include设置空 ’ ’ 每个页面都将会缓存
● exclude的优先级高于include 使用exclude后

关于keep-alive的基本用法

<keep-alive>
  <component :is="view"></component>
</keep-alive>

使用includes和exclude:

<keep-alive include="a,b">
  <component :is="view"></component>
</keep-alive>

<!-- 正则表达式 (使用 `v-bind`) -->
<keep-alive :include="/a|b/">
  <component :is="view"></component>
</keep-alive>

<!-- 数组 (使用 `v-bind`) -->
<keep-alive :include="['a', 'b']">
  <component :is="view"></component>
</keep-alive>

2.2 include和exclude无效问题

使用include/exclude 属性需要给所有vue类的name赋值(注意不是给route的name赋值),否则 include/exclude不生效

export default {
 name:'TableList', // include 或 exclude所使用的name
 data () {
  return {}
  },
}

设置了 keep-alive 缓存的组件,会多出两个生命周期钩子(activated与deactivated):
● 首次进入组件时:beforeRouteEnter > beforeCreate > created> mounted > activated > … … > beforeRouteLeave > deactivated
● 再次进入组件时:beforeRouteEnter >activated > … … > beforeRouteLeave > deactivated

2.3 缓存后如何获取数据

解决方案可以有以下两种:
● beforeRouteEnter
● actived
beforeRouteEnter
每次组件渲染的时候,都会执行beforeRouteEnter

beforeRouteEnter(to, from, next){
    next(vm=>{
        console.log(vm)
        // 每次进入路由执行
        vm.getData()  // 获取数据
    })
},

actived
在keep-alive缓存的组件被激活的时候,都会执行actived钩子

activated(){
   this.getData() // 获取数据
},

注意:服务器端渲染期间avtived不被调用

2.4 联系

HTTP和TCP中的keep-alive和KeepAlive
● HTTP协议(七层)的Keep-Alive意图在于连接复用,希望可以短时间内在同一个连接上进行多次请求/响应。核心在于:时间要短,速度要快。
● TCP协议(四层)的KeepAlive机制意图在于保活、心跳,检测连接错误。核心在于:虽然频率低,但是持久。
(当一个TCP连接两端长时间没有数据传输时(通常默认配置是2小时),发送keepalive探针,探测链接是否存活。)
可看文章:
HTTP中的keep-alive—1
HTTP中的keep-alive—2
HTTP中的keep-alive—3

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值