keep-alive 与 el-tabs 的 lazy 属性产生的初始activated函数不执行

问题

  • router-view 外层包裹了 keep-alive 组件,A页面使用了 el-tabs 中的 el-tab-pane,并配置了属性 lazy(用于性能控制,点击才渲染)
    • 正常不使用 lazy 的组件在一开始就会执行 createdactivated 生命周期,再次进入A页面时,组件的 activated 生命周期也会执行
    • 使用 lazy 的组件,A页面一开始不会渲染该组件,点击该组件后,也只会执行组件的 created 函数,离开当前A页面后,也不会销毁 lazy 组件,再次进入A页面,使用 lazy 的组件会自动执行 activated 生命周期,而不会执行 created
  • bug问题:更新接口在 created 内调用,离开页面再进入页面,没有触发 created,数据未更新

解决

  • 最简单:不使用 lazy,组件直接使用 activated 更新数据,第一次进入和第二次进入都会执行
  • 依旧使用lazy的情况下考虑性能:在 lazy 组件中同时使用 createdactivated 生命周期,并将更新数据的函数放在 activated 函数中,created 函数里利用 this.$options 去获取 activated 生命周期,会获取到一个数组,直接执行, 测试发现,不会在一开始就执行2个函数,所以初始点击也不会将更新函数执行2次
// 父组件
<el-tabs v-model="activeStep">
	...
	<el-tab-pane label="管理" name="tab8" lazy>
	<ProcessPermission></ProcessPermission>
	...
</el-tab-pane>

// ProcessPermission 组件
  created() {
    console.log('created -----')
    this.queryParams.roleId = this.$route.query.id
    this.getOrganization() // 全局数据无需更新
    
	// 通过 this.$options.activated 可以获取到一个函数数组,可能为空
    for (let fun of this.$options.activated || []) {
      fun.call(this)
    }
  },
  activated() {
    console.log('activated -----')
    this.queryParams.roleId = this.$route.query.id
    // 需要执行 this.$refs, 所以使用 this.$nextTick
    this.$nextTick(() => {
      this.accessRight('access', true)
    })
  },
  • 考虑性能并且当前组件会作为全局页面被使用(推荐):此时使用第二种方法会导致更新接口在初始执行两次,lazy 组件使用时传入要给参数判断, 在 created 生命周期里判断该参数,决定是否强制执行一次 activated 函数
//page页面-正常使用该组件,组件的created和activted都与页面的执行时机相同
<template>
  <processPermission />
</template>

// 父组件
<el-tabs v-model="activeStep">
	...
	<el-tab-pane label="管理" name="tab8" lazy>
	<ProcessPermission :lazy="true"></ProcessPermission>
	...
</el-tab-pane>

// ProcessPermission 组件
  props: {
  	lazy: false
  }
  created() {
  	console.log('created')
  	this.queryParams.roleId = this.$route.query.id
    this.getOrganization()
    
    // 非lazy组件不需要在 created 中执行 activated 函数,vue会自动执行created和ctivated
    if (!this.lazy) return
    for (let fun of this.$options.activated || []) {
      fun.call(this)
    }
  },
  ctivated() {
    console.log('activated') // 在 finally 前执行
    this.queryParams.roleId = this.$route.query.id
    this.$nextTick(() => {
      this.accessRight('access', true)
    })
  },
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值