router-view

在使用vue-router的同时使用keep-alive是一个很常见需求。用户可能会希望某些页面进行keep-alive缓存,以方便在路由之间跳转时保留之前操作的信息。

但是在keep-alive的同时某些情况下我们又不希望它进行缓存,我们希望某些页面是缓存的,而某些页面不进行缓存。这方面的解决方案在网上已经有很多讨论了。

方案讨论

常见的方案有以下两种:

  1. 使用两个 router-view 分别显示不同的路由
xml 复制代码
html复制代码<keep-alive>    <router-viewv-if="$route.meta.keepAlive">        <!-- 这里是会被缓存的视图组件,比如 Home! -->    </router-view></keep-alive><router-viewv-if="!$route.meta.keepAlive">    <!-- 这里是不被缓存的视图组件,比如 Edit! --></router-view>

经过我的测试发现,这种方法根本没有进行缓存,即使进行了缓存,从逻辑上来说,从不缓存页面 切换到已缓存页面 ,由于v-if的存在,原先的缓存页面也被清除了,所以根本达不到缓存的结果。

  1. 使用keep-alive组件的include参数配置
bash 复制代码
html复制代码<template>    <router-viewv-slot="{ Component }">        <keep-alive:include="store.cachedRoutes">            <component:is="Component" />        </keep-alive>    </router-view></template>

通过遍历routes数组,将组件存到vuex等地方,并通过keep-aliveinclude参数配置进行keep-alive的组件。这种方案不是说不可以,只是有些繁琐,配置起来需要花费一些时间。

我的方案

我有一种非常简单(且优雅)的方案:不需要配置,不需要双router-view,只需要借助一个小小的key参数。

使用vue的人都知道,在渲染列表的时候,通常需要指定key参数,有时候不指定key参数的代码,lint插件还会报错,浏览器控制台也会显示警告。

大家都只知道key参数可以提高渲染速度,在vue进行diff算法时提供key可以加快diff运算。

但是key参数还有一种神奇用法:强制重新渲染组件(或者说强制重新构建更为贴切)。正是因为diff算法key的比较属于第一优先级的位置,只要组件的key变化了,vue会认为这个组件已经变化,这时将不再判断组件的其他成分,直接构建一个新的组件覆盖原组件。

所以解决keep-alive情况下缓存与不缓存组件共存只需要一行简单的key配置:

bash 复制代码
html复制代码<router-viewv-slot="{Component, route}">  <keep-alive>    <component:is="Component":key="route.path + (route.meta.keepAlive ? '' : Math.random())" />  </keep-alive></router-view>

首先通过router-viewv-slot参数拿到route数据。然后在component组件上配置keykeep-alive的页面就使用route-path作为key,而不进行keep-alive的页面就在route-path的基础上加一个随机数。这样就可以保证非keep-alive的页面会强制刷新。这样就解决了困扰我们已久的问题,而且还不需要额外的配置。

我称之为:一键(key)解决方案

作者:George_Tz 链接:juejin.cn/post/727226... 来源:稀土掘金 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

RotuerView 组件暴露了一个插槽,可以用来渲染路由组件:

template

xml 复制代码
<router-view v-slot="{ Component }">  <component :is="Component" /></router-view>

上面的代码等价于不带插槽的<router-view />,但是当我们想要获得其他功能时,插槽提供了额外的扩展性。

KeepAlive & Transition

当在处理KeepAlive组件时,我们通常想要保持路由组件活跃,而不是 RouterView 本身。为了实现这个目的,我们可以将 KeepAlive 组件放置在插槽内:

template

xml 复制代码
<router-view v-slot="{ Component }">  <keep-alive>    <component :is="Component" />  </keep-alive></router-view>

类似地,插槽允许我们使用一个Transition组件来实现在路由组件之间切换时实现过渡效果:

template

xml 复制代码
<router-view v-slot="{ Component }">  <transition>    <component :is="Component" />  </transition></router-view>

juejin.cn/post/713794...

相关推荐
没资格抱怨14 分钟前
vue3中利用路由信息渲染菜单栏
前端·vue.js
TttHhhYy17 分钟前
vue写后台管理系统,有个需求将所有的$message消息提示换成确认框来增强消息提示效果,遇到嵌套过多的情况,出现某些问题
前端·javascript·vue.js·anti-design-vue
FIRE1 小时前
uniapp小程序分享使用canvas自定义绘制 vue3
前端·小程序·uni-app
四喜花露水1 小时前
vue elementui el-dropdown-item设置@click无效的解决方案
前端·vue.js·elementui
jokerest1231 小时前
web——sqliabs靶场——第五关——报错注入和布尔盲注
前端
谢尔登2 小时前
前端开发调试之 PC 端调试
开发语言·前端
每天吃饭的羊2 小时前
在循环中只set一次
开发语言·前端·javascript
_默_5 小时前
adminPage-vue3依赖DetailsModule版本说明:V1.2.1——1) - 新增span与labelSpan属性
前端·javascript·vue.js·npm·开源
也无晴也无风雨6 小时前
深入剖析输入URL按下回车,浏览器做了什么
前端·后端·计算机网络
Martin -Tang7 小时前
Vue 3 中,ref 和 reactive的区别
前端·javascript·vue.js