Vue 2 <keep-alive> 不能与 <router-view> 和密钥一起使用
Posted
技术标签:
【中文标题】Vue 2 <keep-alive> 不能与 <router-view> 和密钥一起使用【英文标题】:Vue 2 <keep-alive> not working with <router-view> and key 【发布时间】:2017-04-15 08:54:12 【问题描述】:我正在使用带有一系列组件(如选项卡)的 vue-router。每个<router-link>
是一个选项卡,下面的空格是<router-view>
。其中两个选项卡是具有不同过滤器的相同组件,假设它们是products
,路由器添加了一个过滤参数:/products/new
& /products/sale
。
products
内部是单独的 product
组件,这些组件会在路由打开时安装。我的问题是,当我在路由之间切换并更改过滤器参数时,product
组件每次都会重新安装。我想缓存它们,这样来回切换更容易。为此,我设置了<keep-alive>
并将:key='$route.fullPath'
添加到我的<router-view>
,但它们似乎没有被缓存。当我在products
之间切换时,每个product
仍在触发mounted()
事件。
<keep-alive>
<router-view :key='$route.fullPath'></router-view>
</keep-alive>
我是否应该将每个 products
视图变成一个单独的组件?
【问题讨论】:
试试这个答案,虽然这是 vue 2+:keep-alive and router-view 【参考方案1】:要在路由器视图中使用keep-alive,您应该在视图路由器上使用唯一键,如下所示:
<keep-alive>
<router-view :key="$route.fullPath"></router-view>
</keep-alive>
不要忘记在保持活动状态时使用 max 属性来防止内存开销
<keep-alive max="5">
或者只包含想要缓存的组件:
<keep-alive include="FirstComp,SecondComp">
并且对于组件内的每个组件,如果您想要缓存,则需要保持它们处于活动状态
<keep-alive>
<product></product>
</keep-alive>
【讨论】:
注意:<keep-alive include="FirstComp,SecondComp">
仅适用于命名组件(具有 'name' 属性的组件)。【参考方案2】:
Vue 3 - 工作示例
当我从上面尝试解决方案时(在 Vue 3 中)我在控制台中得到了这个
[Vue Router warn]: <router-view> can no longer be used directly inside <transition> or <keep-alive>.
Use slot props instead:
<router-view v-slot=" Component ">
<keep-alive>
<component :is="Component" />
</keep-alive>
</router-view>
所以我就这样把它复制到了App.vue中……
// App.vue
...
<router-view v-slot=" Component ">
<keep-alive>
<component :is="Component" />
</keep-alive>
</router-view>
...
它有效:)
【讨论】:
【参考方案3】:我认为您无法使用keep-alive
缓存router-view
。来自keep-alive
的documentation:
keep-alive 不适用于功能组件,因为它们没有要缓存的实例。
而router-view
是一个功能组件,来自documentation:
该组件是一个功能组件,它为给定路径呈现匹配的组件。
要完成这项工作,您需要在 keep-alive
中添加动态组件,如下所示:
<keep-alive>
<products ></products>
</keep-alive>
【讨论】:
您好,感谢您指出这一点!想到的第一个解决方案是删除<router-view>
并放回我的动态组件,例如:<keep-alive> <component v-bind:is="$route.name"/> </keep-alive>
其中路由的名称将是组件的名称。这在路由方面有效,但在两个版本之间单击时组件仍在重新安装:\
似乎不再是真的了。引用router documentation:Since it's just a component, it works with <transition> and <keep-alive>. When using the both together, make sure to use <keep-alive> inside
@oliverpool 您可以引用所有您想要的内容,但该文档示例不起作用。【参考方案4】:
看看我在这里为 vue 2+ 发布的内容:
vue.js keep-alive and router-view
如果您想根据路由 url 交换内容,您可以将子项添加到您的 routes.js 文件并以这种方式绑定参数。例如,如果您想让您的组件保持活动状态,但需要从部分路径更改数据,您可以执行以下操作:
path: 'products', component: Products, ...,
children: [
path: 'Overview/:name', props: true, component: Overview ,
path: 'Overview/:name/:id', props: true, component: Details
]
您可以先路由到 /Products,然后说用户单击图像或您想要路由到 /Products/Overview/Memes 的任何列表,然后在用户单击可以路由到 /Products/Overview 的特定 meme 之后/Memes/MrPotatoHead 并让组件在 Mr Potato Head 或类似的东西上加载数据。
重要的是要注意 Products 组件将保持活动状态,但子组件不会。即使您将子组件模板包装在 keep-alive 中,它也会被销毁:
destroy nested keep-alive components
【讨论】:
【参考方案5】:仅仅因为您的组件被重新安装并因此在 mounted
钩子上触发您的函数并不意味着它曾经被销毁。要测试它是否保持活动状态,请在 destroyed
钩子上记录一些内容,如果它没有触发控制台日志,则 keep-alive
正在工作。我已经运行了你的相同代码,它似乎至少在 Vue 2 中工作。
【讨论】:
以上是关于Vue 2 <keep-alive> 不能与 <router-view> 和密钥一起使用的主要内容,如果未能解决你的问题,请参考以下文章