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活动,特别是有一定统一结构的活动,都要码一个重复的轮子.后来接到一个基于模板的活动设计系统的需求,便有了下面的内容.借油开车. 组件化 需求一到,接就是怎 ...
随机推荐
- 使用百度网盘+Git,把版本控制托管到云端,附精彩评论
http://www.cnblogs.com/vajoy/p/3929675.html 我试过多个这种双向同步的网盘,在网络状况不好.系统卡顿以及某些程序BUG的情况下,同步会有错乱现象,尤其是多个电 ...
- jQuery仪表盘指示器动画插件 6种仪表样式
土豆网同步更新:http://www.tudou.com/plcover/VHNh6ZopQ4E/ 使用HTML 创建Mac OS App 视频教程. 官方QQ群: (1)App实践出真知 434 ...
- Bamboo 0.2.11 发布,HAProxy 自动配置
Bamboo 0.2.11 发布,此版本更新内容如下: 新特性 提供更多的模板字符串函数:strings.Split, strings.Join,strings.Replace, strings.T ...
- UITableViewStyleGrouped 设置表头出现section不为0的问题
UITableViewStyleGrouped 设置表头出现section不为0的问题 1.如果使用UITableViewStylePlain样式的表格,那么header是会在表格滑动的时候在顶部悬浮 ...
- SYN2136型 北斗NTP网络时间服务器
SYN2136型 北斗NTP网络时间服务器 北斗NTP网络时间服务器时间服务器使用说明视频链接: http://www.syn029.com/h-pd-109-0_310_36_-1.html 请将 ...
- Spring Boot入门篇(基于Spring Boot 2.0系列)
1:概述: Spring Boot是用来简化Spring应用的初始化开发过程. 2:特性: 创建独立的应用(jar|war形式); 需要用到spring-boot-maven-plugin插件 直接嵌 ...
- python网络编程(转)
本文代码转自廖雪峰老师的python教程 网络编程底层其实就是一个socket,代表两台机器之间的一个连接. s = socket.socket(socket.AF_INET, socket.SOCK ...
- ABP开发框架前后端开发系列---(11)菜单的动态管理
在前面随笔<ABP开发框架前后端开发系列---(9)ABP框架的权限控制管理>中介绍了基于ABP框架服务构建的Winform客户端,客户端通过Web API调用的方式进行获取数据,从而实现 ...
- Oracle数据库视图的创建以及使用
创建视图语句: CREATE [OR REPLACE] [FORCE|NOFORCE] VIEW view_name [(alias[, alias]...)] AS subquery [WITH C ...
- 利用Settings.bundle切换网络环境
目的:一次性打包,测试可以去iPhone设置,找到APP,点击后然后可以自主切换网络环境(测试.预生产.正式).关闭APP重新打开生效. 撸起袖子加油干…… 1.生成并设置Setting.bundle ...