【发布时间】:2019-08-20 17:31:55
【问题描述】:
我有两个组件。一个父母和一个孩子。父级根据v-if 加载子级。然后孩子通过$emit发送一个事件告诉父母移除孩子。
简单地说。
家长:
data() {
return {
show: false
}
},
// template:
<div>
<div @click="show = !show">Toggle</div>
<child-component
v-if="show"
@close="show = false"
/>
</div>
孩子:
template:
<div>
Some Content
<div @click="$emit('close')">Close</div>
</div>
问题是当$emit('close') 被触发时,子元素从DOM 中移除,但组件并没有从内存中清除。
如果父母使用toggle 按钮删除孩子,它确实会从内存中清除孩子。
我也尝试过使用Vuex store 和$root.data,但这也会导致内存泄漏。
换句话说,如果子进程向父进程发出信号,表明它应该被删除,它就会被保存在内存中。但是,如果父级直接删除子级(没有来自子级的任何信号),它就会从内存中删除...
任何想法为什么会发生这种情况以及我应该做些什么来防止这种内存泄漏?有必要让孩子发出将其移除的信号。
[编辑] - 代码笔中的演示。 https://codepen.io/tomshort5/pen/BaBLXvb
内存快照
通过在某些操作后制作内存快照可以最清楚地看到这一点。当页面加载时,我们有一个 Vue 实例。
点击切换后,会按预期创建一个 VueComponent。
通过事件触发child被移除后,VueComponent不会从内存中移除。将其与再次单击“切换”进行比较时,它确实显示该组件已从内存中删除。
【问题讨论】:
-
是什么让你认为存在内存泄漏?
-
component is not cleared from memory你是如何识别内存泄漏的? -
我无法用您提供的示例重现您的问题。它正确地显示了调用其被销毁的生命周期钩子的组件。 codesandbox.io/s/vue-template-ptpxc?fontsize=14 显然它只会在GC运行时清除内存,但从那时起内存就被清除了。
-
我已经创建了一个 codepen,可以在这里重现:codepen.io/tomshort5/pen/BaBLXvb 在开发者控制台的内存选项卡中。拍摄快照并按“Vue”过滤
-
这很奇怪。简短的回答是,由于某种原因,它仍然在第一个组件的 $children 列表中。长答案是:为什么?!
标签: vue.js