网络编程
位置:首页>> 网络编程>> JavaScript>> vue自定义keepalive组件的问题解析

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

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

标签:vue,keepalive,组件

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

0
投稿

猜你喜欢

  • 本文实例讲述了sql server实现递归查询的方法示例。分享给大家供大家参考,具体如下:有时候面对树结构的数据时需要进行递归查询,网上找了
  • 字符串格式化输出是python非常重要的基础语法,今天就把三种格式化输出做一个简单的总结,希望对大家有帮助。格式化输出:内容按照一定格式要求
  • 常公司的开发环境都会布置在内网,然后会有公共的服务器让大家在上面进行开发,测试,所以经常会有ssh连接服务器,或者本地mysql clien
  •  LNMP一键包安装的Mysql默认开启Mysql日志,如果网站对数据库读写较为频繁的话可能会产生大量日志,并占用磁盘空间,还有可
  • 目录生活中的例子慢查询如何去优化countlimit最大值最小值min&max生活中的例子我们是否看到过在公司中许多查询语句都是se
  • 目录1、read_sql_query 读取 mysql2、to_sql 写入数据库 要实现 pandas 对 mysql 的读写需
  • 我们在进行程序操作的时候,因为各种原因,需要通过不同的形式返回到之前的对象。不知道小伙伴们会几种返回的函数方法呢?今天要介绍的是findal
  • Access SQL 函数 收藏 ▲日期/时间CDate  将字符串转化成为日期 select CDate("2005/
  • 一 、背景一般在数据仓库环境中,我们可以很方便的使用row_number函数根据某个维度来对数据进行分组,实现每个组内数据编号排序的效果。如
  • 原文地址https://www.codementor.io/python/tutorial/advanced-use-python-deco
  • 看到sam关于max-height的文章,觉得按捺不住了。sam注重于样式表的写法,过多的要求div+css的布局,sam可是追求艺术的人哦
  • 字符串索引示意图字符串切片也就是截取字符串,取子串Python中字符串切片方法字符串[开始索引:结束索引:步长]切取字符串为开始索引到结束索
  • 一、连接MYSQL。  格式: mysql -h主机地址 -u用户名 -p用户密码&nbs
  • 本文利用 MySQL的扩展功能 REPLACE INTO 来生成全局id,REPLACE INTO和INSERT的功能一样,但是当使用REP
  • 如何 在Access中选择指定日期前的记录?我知道,在Access中不能使用DateDiff,那么我们怎样才能选择指定日期前的若干记录呢?虽
  • 本文实例讲述了python实现忽略大小写对字符串列表排序的方法,是非常实用的技巧。分享给大家供大家参考。具体分析如下:先来看看如下代码:st
  • 0 前置知识sync.WaitGroupsync.WaitGroup是等待一组协程结束。它实现了一个类似任务队列的结构,可以向队列中加入任务
  • 一. 创建列表列表(list)作为Python中基本的数据结构,是存储数据的容器,相当于其它语言中所说的数组。模拟出的结构如下:创建列表有两
  • 听说最近流行JQ风格的语法,不流行EXT风格了一.//ajax类fw=window.fw||{};fw.ajax = { &nbs
  • 车牌识别在高速公路中有着广泛的应用,比如我们常见的电子收费(ETC)系统和交通违章车辆的检测,除此之外像小区或地下车库门禁也会用到,基本上凡
手机版 网络编程 asp之家 www.aspxhome.com