Skip to content

KeepAlive + Transition + v-if 同时使用时会导致时会导致内存泄漏的2个bug #10620

Description

@wcldyx

Vue version

3.4.21

Link to minimal reproduction

https://stackblitz.com/edit/vitejs-vite-futfv6?file=src%2FApp.vue

Steps to reproduce

测试的时候注意自己创建一个新项目测试,因为stackblitz上看内存占用不方便

有两个bug

第一个bug: KeepAlive + Transition + v-if 同时使用时会导致时会导致内存泄漏。

如图所示,通过点击toggle按钮用v-if 不停的切换显示隐藏组件,你会看到内存一直没有被释放。

image
动画1

单独使用KeepAlive 时在通过v-if隐藏组件时内存会自动释放。

动画2

第二个bug: 在 mode="out-in"时通过v-if切换并同时移除include里面的key时,对应的组件没有被正常卸载(没有触发onUnmounted), 内存也没有得到释放。

mode为默认值时,组件能正常卸载

动画3

mode="out-in" 时,组件没有被正常卸载

动画4

What is expected?

修复以上bug

What is actually happening?

KeepAlive + Transition + v-if 同时使用时会导致时会导致内存泄漏,同时在 Transition 的 mode="out-in"时,组件没有被正常卸载或销毁

System Info

No response

Any additional comments?

No response

以下是完整代码

<script lang="ts" setup>
import { ref, defineComponent, h, onUnmounted } from 'vue';
// import A from "./A.vue";

const show = ref(true);
const include = ref(['A']);

const A = defineComponent({
  name: 'A',
  setup() {
    const list = ref(new Array(1000000).fill({ name: 'hello' }));
    console.log('安装');
    onUnmounted(() => {
      console.log('卸载');
    });
    return () => h('h1', 'A组件' + list.value.length);
  },
});

function toggle() {
  show.value = !show.value;
  if (show.value) {
    include.value = ['A'];
  } else {
    include.value = [];
  }
}
</script>
<template>
  <div>include:{{ include }}</div>
  <button @click="toggle">toggle</button>
  <Transition mode="out-in">
    <KeepAlive :include="include">
      <A v-if="show" />
    </KeepAlive>
  </Transition>
</template>

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions