vue中如何自定义keepalive组件,缓存问题怎样解决
Admin 2022-08-12 群英技术资讯 683 次浏览
前一阵来了一个新的需求,要在vue项目中实现一个多开tab页面的功能,本来心想,这不简单嘛就是一个增加按钮重定向吗?(当然如果这么简单我就不写这个文章了)。很快写完,提交测试。测试大哥很快就提交了一个问题:"你两个tab页访问同一个链接,怎么还是个联动的呢?"。我擦,这指定是缓存的问题。
keep-alive组件是使用
include
exclude
这两个属性传入组件名称来确认哪些可以被缓存的
<keep-alive exclude="a,b,c" > <router-view></router-view> </keep-alive>
我们在看一下源码,看看人家是怎么实现的(这两张图截的真难看)
主要逻辑(直说上述代码)就是根据传入的
include
,exclude
两个属性传入数组,根据当前访问的组件名称判断。我们相同链接都访问同一个组件名称(name)相同,第二次访问的时候,链接指向的是同一个组件,因为使用组件的name作为缓存key,此时会被认为是读取缓存操作,就会直接加载缓存并渲染,所以出现了两个tab页访问同一个链接,出现联动情况
这个比较简单之前是因为组件name当key导致的,那我们就不使用组件的name作为key了,改为name+tab的index作为key。
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的作用是用来区分同一个组件是不是重复使用一个实例。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
three.js镜头追踪移动的实现难点有哪些?在实际项目的操作过程或是学习过程中,不少人都会遇到这样的问题,接下来就让小编带大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
其实在很多文章都会写call,apply,bind,但个人觉着如果不弄懂原理,是很难理解透的,所以这篇文章主要介绍了JavaScript中call、apply、bind实现原理的相关资料,需要的朋友可以参考下
parseInt()的作用是什么?他是js原生的方法,是用来把数字字符串转化为Number类型的数字的,还有他只是转化整数部分。
目录作用域全局作用域作用域中的错误局部作用域with弊端数据泄露性能下降letconst作用域链闭包闭包对作用域链的影响匿名函数的赋值使用let作用域作用域,也就是我们常说的词法作用域,说简单点就是你的程序存放变量、变量值和函数的地方。根据作用范围不同可以分为全局作用域和局部作用域,简单说来就是,花括号{}括起来的代码
这篇文章主要为大家详细介绍了小程序实现上下切换位置,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008