Vue匿名组件使用keep-alive后动态清除缓存
在使用Vue开发管理系统项目的时候,为了保存页面的浏览状态,我们可以使用内置组件keep-alive来缓存组件内部状态,避免重新渲染。
<keep-alive>
<router-view></router-view>
</keep-alive>
被keep-alive包裹的动态组件或router-view会缓存不活动的实例,再次被调用这些被缓存的实例会被再次复用,而不需要再次发送HTTP请求。对于使用tabs标签页打开页面时,这正是我们想要的效果。但是这样做同时也存在一个问题,就是被keep-alive包裹的组件会保持最后一次请求数据的渲染结果,即使我们关闭了tabs页,再次打开时依旧是上一次的状态。这时,我们就得用上include、exclude属性来对缓存的组件进行筛选。
Props:
include- 字符串或正则表达式。只有名称匹配的组件会被缓存。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>
有了include和exclude对组件进行筛选,然后动态的记录tabs中打开的组件名,这就完美的解决了动态缓存的问题。所以在配置路由文件时,我们必须得先import组件,然后以组件名调用。
import HelloWorld from '@/components/HelloWorld'
routes: [
{
path: '/',
name: 'HelloWorld',
component: HelloWorld
}
但是,在项目开发中,为了提升页面加载的速度,一般会采用路由懒加载的方式加载路由组件,这时调用的组件不再是通过组件名,而是匿名组件。
{
path: '/home',
name: 'home',
component: resolve => require(['@/components/learn/home'], resolve)
}
可是,官方文档指出:
匹配首先检查组件自身的 name 选项,如果 name 选项不可用,则匹配它的局部注册名称 (父组件 components 选项的键值)。匿名组件不能被匹配。
这样一来include和exclude就无效了。。。
额(⊙o⊙)…目前我们项目就是这样通过匿名组件调用的,所以就没有使用keep-alive组件。这时领导试用系统,咦...我这打开的页面怎么每次点进去都重置了页面内容,怎么不能像打开网页那样,我看到哪就给保存那时的状态呢,不过由于大家说弄不了,就把这个功能推掉了。
但是这段时间正好手中的事告一段落了,有空余时间,并本着有问题就得解决的原则,就自己琢磨起来。首先使用keep-alive进行全站缓存这个是肯定不行的,使用者肯定得说:怎么我把页面关了打开后还是之前的呢。。。所以,感觉这是一个很复杂的问题,要不然早就加上了。
于是乎,打开度娘寻找心灵安慰。找吖找吖找,也不知在清一色的复制粘帖中摸索了多久,除了使用include来解决动态缓存问题,完全没有对匿名组件的解决方案。就在快要放弃和度娘交流时,突然眼前闪过一丝希望的光芒!
终于发现了大神研究出的可行方案:Vue 全站缓存之 keep-alive : 动态移除缓存 https://juejin.im/post/5b610da4e51d45195c07720d。
在茫茫代码中,他一眼就看到了隐藏在角落里的vue-component-12-keep-alive,然后才有了完美的解决方案。那就是使用Vue.mixin的方法拦截了路由离开事件,并在该拦截方法中实现了销毁页面缓存的功能。
// 全局混入,关闭tab时清除组件缓存
Vue.mixin({
beforeRouteLeave(to, from, next) {
let flag = true
this.$store.state.options.forEach(e => { // options存储打开的tabs的组件路由
if(from.path == e.route) {
flag = false
}
})
if(flag && this.$vnode.parent && this.$vnode.parent.componentInstance.cache) {
let key = this.$vnode.key // 当前关闭的组件名
let cache = this.$vnode.parent.componentInstance.cache // 缓存的组件
let keys = this.$vnode.parent.componentInstance.keys // 缓存的组件名
if(cache[key] != null) {
delete cache[key]
let index = keys.indexOf(key)
if(index > -1) {
keys.splice(index, 1)
}
}
}
next()
}
})
不过在这之前我们还得解决一个问题,由于此方法是拦截了路由离开事件,而当我们关闭不是当前激活的标签页时是不会触发路由离开事件的,这就会导致清除该缓存失效,所以我们得在关闭不激活的标签页时先模拟一次点击事件才能达到预期的效果。
// 移除tab标签
tabRemove (targetName) {
let event = new Event('click')
document.getElementById("tab-" + targetName).dispatchEvent(event) // 触发点击事件 this.$store.commit('delete_tabs', targetName);
if (this.activeIndex === targetName) {
// 设置当前激活的路由
if (this.openTab && this.openTab.length >= 1) {
this.$store.commit('set_active_index', this.openTab[this.openTab.length - 1].route);
this.$router.push({ path: this.activeIndex });
} else {
this.$router.push({ path: '/' });
}
}
}
OK,这样就完美了解决了匿名组件动态清除缓存的问题了。
Vue匿名组件使用keep-alive后动态清除缓存的更多相关文章
- Vue UI组件 开发框架 服务端 辅助工具 应用实例 Demo示例
Vue UI组件 开发框架 服务端 辅助工具 应用实例 Demo示例 element ★11612 - 饿了么出品的Vue2的web UI工具套件 Vux ★7503 - 基于Vue和WeUI的组件库 ...
- Vue父组件向子组件传递一个动态的值,子组件如何保持实时更新实时更新?
原文:https://blog.csdn.net/zhouweixue_vivi/article/details/78550738 2017年11月16日 14:22:50 zhouweixue_vi ...
- vue教程3-03 vue组件,定义全局、局部组件,配合模板,动态组件
vue教程3-03 vue组件,定义全局.局部组件,配合模板,动态组件 一.定义一个组件 定义一个组件: 1. 全局组件 var Aaa=Vue.extend({ template:'<h3&g ...
- vue父组件向子组件动态传值的两种方法
在一些项目需求中需要父组件向子组件动态传值,比如我这里的需求是,父组件动态通过axios获取返回的图片url数组然后传给子组件,上传图片的子组件拿到该数组后进行遍历并展示图片,因为有时候获取到的会是空 ...
- c# 把一个匿名对象赋值给一个Object类型的变量后,怎么取这个变量? c# dynamic动态类型和匿名类 详解C# 匿名对象(匿名类型)、var、动态类型 dynamic 深入浅析C#中的var和dynamic
比如有一个匿名对象,var result =......Select( a=>new { id=a.id, name=a.name});然后Object obj = result ;我怎 ...
- [vue]子组件通过props获取父组件数据以及使用watch解决动态数据不生效问题
父子组件的传值,在Vue官方也写得很清楚,父组件中使用v-bind绑定传送,子组件使用props接收. 父组件通过v-bind绑定数据: <template> <router-vie ...
- Vue(七) 组件详解
组件 (Component) 是 Vue.js 最核心的功能,也是整个框架设计最精彩的部分,当然也是最难掌握的. 组件与复用 组件用法 组件与创建 Vue 实例类似,需要注册后才可以使用.注册有全局注 ...
- vue.js组件化开发实践
前言 公司目前制作一个H5活动,特别是有一定统一结构的活动,都要码一个重复的轮子.后来接到一个基于模板的活动设计系统的需求,便有了下面的内容.借油开车. 组件化 需求一到,接就是怎么实现,技术选型自然 ...
- VUE.JS组件化
VUE.JS组件化 前言 公司目前制作一个H5活动,特别是有一定统一结构的活动,都要码一个重复的轮子.后来接到一个基于模板的活动设计系统的需求,便有了下面的内容.借油开车. 组件化 需求一到,接就是怎 ...
随机推荐
- C#图片处理之:旋转图片90度的整数倍
原文:C#图片处理之:旋转图片90度的整数倍 旋转图片90的整数倍那真是太简单了. public static Bitmap KiRotate90(Bitmap img) ...
- CWnd和HWND的区别(hWnd只是CWnd对象的一个成员变量,代表与这个对象绑定的窗口)
所有控件类都是CWnd类的派生类,CWnd的所有成员函数在控件类中都可以使用.在MFC中,CWnd类是一个很重要的类,它封装了Windows的窗口句柄HWND.在Windows编程中, ...
- C++数组指针、指针数组、函数指针的核心概念
1.什么叫数组指针? 数组指针:一个指向一维或者多维数组的指针. 比如:int * b=new int[10];指向一维数组的指针b ; 注意,这个时候释放空间一定要delete [] ,否则会造成内 ...
- Ceph OpenSSL
Ceph OpenSSL 1. SSL介绍 SSL(Secure Sockets Layer 安全套接层),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信 ...
- uni-app中Vuex的引用
//store 中 store.js import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) const store = new Vue ...
- 使用LinkedList模拟一个堆栈或者队列数据结构。
堆栈:先进后出 First in last out filo 队列:先进先出 First in last out filo使用LinkedList的方法,addFirst addLast getFir ...
- DHCP服务部署流程
为某一局域网部署DHCP [root@dhcp ~]# yum install -y dhcp[root@dhcp ~]# rpm -ql dhcp/usr/sbin/dhcpd:dhcp服务进程 / ...
- 用Docker搭建LNMP
程序员经常会说的一句话:在我的机器上是正常的,肯定是你的机器有问题.因此,Docker诞生了,它把应用所需要的一切东西都打包,从而可以很方便地进行部署. Docker 的主要用途,目前有三大类: 提供 ...
- 【Netty整理02-详细使用】Netty入门
重新整理版:https://blog.csdn.net/the_fool_/article/details/83002152 参考资料: 官方文档:http://netty.io/wiki/user- ...
- 【JAVA】我的爬虫
简介:不是很智能的爬虫,效率慢,仅用作自娱自乐,需要观察目标网站的页面然后修改相关正则去获取自己想要的数据 环境:需要Http-client相关jar包,如下,可以去我的下载链接下载: https:/ ...