我正在使用 Vue.js 2.5.x 和 Nuxt 1.4。我相信这是一个与 vue-router 相关的问题。
我在两个不同的 Nuxt 页面上有相同的组件,我想在页面之间导航时保留在布局中(不仅仅是在内存中)。
从生命周期事件的角度来说,一些组件在布局中添加和删除,并触发创建、安装、卸载、销毁的整个生命周期。我了解 keep-alive 是如何工作的,以避免我们希望在布局中重新安装的组件的该过程的创建/销毁开销,这不是这里的问题。
相比之下,当路由改变时,简单的组件似乎根本不会被卸载,就好像 Vue 以某种方式理解这些组件将在两种不同的布局中显示相同,所以它不仅不会销毁/创建它们......布局,甚至不卸载它们。
我试图更好地了解在路由之间导航时允许当前页面的组件保持安装状态的条件。我发现的许多讨论都属于“为什么我的组件不刷新?”的性质。当路由更改发生时,但我实际上遇到了相反的问题:我想保留一个组件及其状态,但该组件正在被销毁。我已经将“key”显式设置为特定的共享值(通常为确保组件卸载而给出的相反建议),但似乎还有比这更深的东西。
同样,为了清楚起见,我不是指“保持活动”试图挂在内存中临时从布局中删除的组件上。我在这里观察并试图理解的似乎是一种不同的行为,其中 Vue 的某些部分将组件识别为两个布局之间的相同,并优化了此类组件的销毁和(重新)创建。这是一个巨大的优化,但在我能找到的任何地方似乎都没有讨论或记录其行为。
我有一个 Nuxt 布局,它在概念上是这样的……
默认.vue:
<template>
<div>
<my-marvelous-header-component />
<nuxt/>
<my-also-marvelous-footer-component />
</div>
</template>
Run Code Online (Sandbox Code Playgroud)
……我有几个 Nuxt 页面看起来像这样……
页-a.vue:
<template>
<section id=mainContent>
<wonderful-component id="wonder1" :key=321 />
<complex-component-with-children :key=123 />
</section>
</template>
Run Code Online (Sandbox Code Playgroud)
页-b.vue:
<template>
<section id=mainContent>
<wonderful-component id="wonder1" :key=321 />
<complex-component-with-children :key=123 />
</section>
</template>
Run Code Online (Sandbox Code Playgroud)
您会注意到这两个页面具有完全相同的组件,并且我尝试使用关键属性来唯一地标识它们,以便向 Vue 传达它们在渲染时是相同的生物。
当我使用 this.$router.push() 在这些页面之间导航时,我的页眉和页脚组件在路由导航中不受干扰(我通过在生命周期钩子中放置一些控制台输出来验证这一点),但是美妙和复杂的组件都被破坏了并且然后重新创建。
我试图回收的两个组件内部都有许多动态创建的子组件,因此 vdom 的状态将与初始页面的原始启动条件有很大不同。美妙或复杂的组件没有任何属性或从模板传递的任何其他数据……它们与上面的布局完全一样。我已经尝试为它们提供一个在模板之间共享的唯一 ID 或键值(以及什么都没有),但无论我尝试过什么,路由器推送都会导致这些组件销毁并重新渲染。
像我的页眉和页脚这样的琐碎组件可以很好地回收利用,我只是想让我的更复杂的组件也有同样的行为。
所以我的主要问题是,什么允许或阻止组件的回收?检查什么来确定组件是否可以回收?有没有办法在路由更改之间发出信号应保留/回收组件?如果不是,我必须在组件之外保留什么才能使其看起来像是在过渡中停留的候选者?
我原以为“key”属性在这里很神奇,但这似乎不起作用,不幸的是浏览 Vue.js 源代码发现这个词被广泛用于命名参数和局部变量......我相信有Vue 中有一个名为“patch()”的函数,它至少处理与新旧组件一致地更新 …