vue自定义keepalive组件的问题解析

作者:神经蛙12138 时间:2024-05-09 15:12:38 

vue自定义keepalive组件

前一阵来了一个新的需求,要在vue项目中实现一个多开tab页面的功能,本来心想,这不简单嘛就是一个增加按钮重定向吗?(当然如果这么简单我就不写这个文章了)。很快写完,提交测试。测试大哥很快就提交了一个问题:"你两个tab页访问同一个链接,怎么还是个联动的呢?"。我擦,这指定是缓存的问题。

为什么会出现这种情况呢

keep-alive组件是使用 include exclude这两个属性传入组件名称来确认哪些可以被缓存的

<keep-alive exclude="a,b,c" >
       <router-view></router-view>
   </keep-alive>

我们在看一下源码,看看人家是怎么实现的(这两张图截的真难看)

vue自定义keepalive组件的问题解析

vue自定义keepalive组件的问题解析

主要逻辑(直说上述代码)就是根据传入的 include, exclude 两个属性传入数组,根据当前访问的组件名称判断。我们相同链接都访问同一个组件名称(name)相同,第二次访问的时候,链接指向的是同一个组件,因为使用组件的name作为缓存key,此时会被认为是读取缓存操作,就会直接加载缓存并渲染,所以出现了两个tab页访问同一个链接,出现联动情况

如何解决这个问题呢

这个比较简单之前是因为组件name当key导致的,那我们就不使用组件的name作为key了,改为name+tab的index作为key。

问题知道了怎么解决呢

vue自定义keepalive组件的问题解析

思路有了撸代码

group-keep-alive.js

function remove(arr, item) {
 if (arr.length) {
   var index = arr.indexOf(item)
   if (index > -1) {
     return arr.splice(index, 1)
   }
 }
}
function getFirstComponentChild(children) {
 if (Array.isArray(children)) {
   for (var i = 0; i < children.length; i++) {
     var c = children[i]
     if (isDef(c) && (isDef(c.componentOptions) || isAsyncPlaceholder(c))) {
       return c
     }
   }
 }
}
function isDef(v) {
 return v !== undefined && v !== null
}
function isAsyncPlaceholder(node) {
 return node.isComment && node.asyncFactory
}
var patternTypes = [String, RegExp, Array]
export default {
 name: 'keep-alive',
 abstract: true,
 computed: {
   // 这里算是一个伪代码
   // 缓存的数组 [{ 'tab1/组件名称':comp, 'tab2/组件名称':comp },{ 'tab1/组件名称':comp, 'tab2/组件名称':comp }]  
   cacheArray() {
     return this.$store.state.xxx.groupCache
   },
   // 当前选中的分组 例:0/1/2... 这里用来读取cache数组的index
   groupIndex() {
     return this.$store.state.xxx.groupIndex
   }
 },
 created: function created() {
   // 当前tab的缓存
   const cache = this.cacheArray[this.groupIndex]
   this.cache = cache || Object.create(null)
   // TODO 页面初始化事件,后续可触发初始化事件
 },
 destroyed: function destroyed(to, form) {
   // TODO 页面离开事件,后续可触发关闭事件
 },
 render: function render() {
   var slot = this.$slots.default
   var vnode = getFirstComponentChild(slot)
   var componentOptions = vnode && vnode.componentOptions
   // check pattern
   var ref$1 = this
   var cache = ref$1.cache
   const key = `${this.groupIndex}/${componentOptions.Ctor.options.name}`
   // 存在key直接读取
   if (cache[key]) {
     vnode.componentInstance = cache[key].componentInstance
   } else {
     // 没有进行缓存
     cache[key] = vnode
   }
   // 写入缓存
   this.$store.dispatch('setGroupCache', {
     cache: this.cache
   })
   return vnode || (slot && slot[0])
 }
}

如何使用

意思一下就行了

<group-keep-alive>
  <router-view :key="key" />
/group-keep-alive>

// key一定要区分
computed: {
   key() {
     return `${选中index}/${fullpath}`
   },
}

主题说完了,整点其他的

1. 在group-keep-alive组件中设置了abstract: true,设置当前组件为抽象组件,我的李姐:就是一个对下一级(包含子元素)事件监听等提前拦截,从而对下一级进行操作

2. router-view :key="key" 这key的作用是用来区分同一个组件是不是重复使用一个实例。

来源:https://juejin.cn/post/7116822615003987982

标签:vue,keepalive,组件
0
投稿

猜你喜欢

  • php实现汉字验证码和算式验证码的方法

    2024-06-07 15:50:15
  • JQuery判断radio(单选框)是否选中和获取选中值方法总结

    2024-04-19 10:24:11
  • pygame实现贪吃蛇小游戏

    2023-04-18 19:09:07
  • MySQL中的主键自增机制详情

    2024-01-18 23:50:54
  • python argparse模块传参用法实例

    2022-01-19 09:53:42
  • python保存网页图片到本地的方法

    2021-05-20 16:15:04
  • ASP技巧:Script块不能放在另一个Script 块内

    2009-08-19 17:17:00
  • ORACLE 数据库RMAN备份恢复

    2024-01-22 19:22:50
  • 用pywin32实现windows模拟鼠标及键盘动作

    2023-07-04 21:26:30
  • 详解Django CAS 解决方案

    2021-12-06 07:52:11
  • JavaScript ES6中const、let与var的对比详解

    2024-05-22 10:37:36
  • pygame实现方块动画实例讲解

    2022-11-01 13:37:46
  • wxPython框架类和面板类的使用实例

    2022-06-29 08:16:27
  • 如何利用Python随机从list中挑选一个元素

    2023-08-04 00:05:54
  • 简单的Python调度器Schedule详解

    2021-09-15 09:49:19
  • Python入门之列表用法详解

    2023-10-04 05:44:50
  • Python中图像算术运算的示例详解

    2023-01-01 19:56:43
  • 解析isset与is_null的区别

    2023-11-21 16:11:44
  • asp无组件实现画简单图形的类

    2004-06-17 13:30:00
  • python数值基础知识浅析

    2021-12-10 07:07:49
  • asp之家 网络编程 m.aspxhome.com