vlambda博客
学习文章列表

vue实现选项卡切换路由不刷新

前言


    昨天做项目时,有一个小需求,就是实现在切换选项卡的时候,已经加载过的选项卡不在进行刷新页面,保存已有操作的样子。

    我们主要用了ElementUI组件库里的<el-tags></el-tags>来实现选项卡的。每个选项卡都是一个路由,点击点击栏目时,有选项卡则自动切换,没有选项卡则新增一个选项卡。

<keep-alive>


    要实现一个路由切换后,页面不刷新的问题,就需要用到vue的一个抽象组件<keep-alive>

用法

    <keep-alive>是包裹动态组件的,会缓存没有活动的组件的实例,而不是销毁组件实例。和 <transition> 相似。<keep-alive>是一个抽象组件,它自身不会出现在父组件中,也不会渲染一个dom元素。

    当组件在<keep-alive>里面被切换时,<keep-alive>有两个生命周期钩子函数会被对应执行,一个是actvateddeactivated。

actvated

    在组件被激活时调用,在组件第一次渲染时也会被调用,之后每次keep-alive激活时被调用。

deactivated。

    在组件被停用时调用。

当引入keep-alive 的时候,页面第一次进入,钩子的触发顺序created-> mounted-> activated,退出时触发deactivated。当再次进入(前进或者后退)时,只触发activated。

在 2.2.0 及其更高版本中,activated 和 deactivated 将会在 <keep-alive> 树内的所有嵌套组件中触发。
主要用于保留组件状态或避免重新渲染。

<!-- 基本 --><keep-alive> <component :is="view"></component></keep-alive><!-- 多个条件判断的子组件 --><keep-alive> <comp-a v-if="a > 1"></comp-a> <comp-b v-else></comp-b></keep-alive><!-- 和 `<transition>` 一起使用 --><transition> <keep-alive> <component :is="view"></component> </keep-alive></transition>

    注意,<keep-alive> 是用在其一个直属的子组件被开关的情形。如果你在其中有 v-for 则不会工作。如果有上述的多个条件性的子元素,<keep-alive> 要求同时只有一个子元素被渲染。

Props

include

字符串或正则表达式。只有名称匹配的组件会被缓存。

<!-- 逗号分隔字符串 --><keep-alive include="a,b"> <router-view :key="$route.path"></router-view></keep-alive><!-- 正则表达式 (使用 `v-bind`) --><keep-alive :include="/a|b/"> <router-view :key="$route.path"></router-view></keep-alive><!-- 数组 (使用 `v-bind`) --><keep-alive :include="['a', 'b']"> <router-view :key="$route.path"></router-view></keep-alive>

    include是用来匹配组件的name选项,不管是局部组件还是全局组件,都会有一个name属性。include只能够匹配name属性,其它无法匹配。多个页面缓存,则可以用字符串的逗号分隔,也可以用数组或者是正则表达式来判断。

exclude

字符串或正则表达式。任何名称匹配的组件都不会被缓存。

<keep-alive exclude="a,b"> <router-view :key="$route.path"></router-view></keep-alive>

    exclude表示匹配的名称都不被缓存,也就是组件名称为a和b的组件不被缓存

max

2.5.0 新增
最多可以缓存多少组件实例。一旦这个数字达到了,在新实例被创建之前,已缓存组件中最久没有被访问的实例会被销毁掉。

<keep-alive :max="10"> <router-view :key="$route.path"></router-view></keep-alive>

max为10,表示缓存组件达到10个时,会销毁最久没有访问的组件。

<keep-alive> 不会在函数式组件中正常工作,因为它们没有缓存实例。

控制缓存


第一种方式

//template<keep-alive> <router-view v-if="$route.meta.keepAlive" :key="key"></router-view></keep-alive><router-view v-if="!$route.meta.keepAlive"></router-view>

    修改key值的话,会清空所有的缓存,当前路由不会刷新

第二种方式

<keep-alive>    <router-view v-if="$route.meta.keepAlive&&isRouterAlive"></router-view></keep-alive><router-view v-if="!$route.meta.keepAlive"></router-view>
this.isRouterAlive= false;this.$nextTick(function(){ this.isRouterAlive= true;})

这种方式会清空所有缓存,当前路由也会被刷新.

第三种方式


<keep-alive> <router-view v-if="$route.meta.keepAlive" :exclude="excludeArray"></router-view></keep-alive><router-view v-if="!$route.meta.keepAlive"></router-view>
this.excludeArray.push('routeName');this.$nextTick(function(){ let index = this.excludeArray.indexOf('routeName'); this.excludeArray.splice(index, 1);})

    通过添加routeName, exclude里面排除组件的缓存,然后又添加回去即可控制某一个组件的缓存,实现清楚指定组件的缓存。

第四种方式

    通过路由守卫修改meta: {keepAlive: true }的值来控制路由需不需要被缓存

实现思路


新增选项卡

    每一次新增选项卡时,都会有对应的路由,获取路由对应的组件的name的名称,动态添加进cacheView的缓存组件中,就可以进行组件缓存。

删除选项卡

    删除选项卡后,需要获取删除选项卡对应组件的name的值,通过字符串匹配或者是数组匹配,删除掉对应的cacheView的缓存组件。

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




更多前端分享,请关注:



前端路人甲