[vue3] Programmatically create Component the memory detached element is raised

( How to manually unmount Vue from the dom element components)[https://github.com/vuejs/vue-next/issues/593]
( Vue3 Creating Component Instances Programmatically)[https://github.com/vuejs/vue-next/issues/2331]

According to the above guidance, write the code as follows

import { createApp, defineComponent } from "vue";

const Toast = defineComponent(() => {
  return () => {
    return <div>toast</div>;
  };
});

const toast = () => {
  const div = document.createElement("div");
  document.body.appendChild(div);

  const toastInstance = createApp(Toast);
  toastInstance.mount(div);

  toastInstance.unmount(div);
  document.body.removeChild(div);
};

const App = defineComponent(() => {
  return () => {
    return (
      <div>
        app
        <button onClick={toast}>toast</button>
      </div>
    );
  };
});

const app = createApp(App);
app.mount("#app");

In this way, a toast div will not be destroyed.

If you comment out these lines,

  const toastInstance = createApp(Toast);
  toastInstance.mount(div);

  toastInstance.unmount(div);

the problem doesn’t exist

What’s wrong with my operation?

1 Like

I don’t understand what problem you’re having. Everything seems to be working correctly to me.

Well, I can’t get the code to create a toaster, but I would think that it doesn’t work to create & destroy a toaster in one method.

Thanks a lot for reply
Maybe it’s not clear what I described, then I will say more in detail

My original intention was to create a pop-up box, remove the pop-up box when I no longer use it, and release the memory

So I tried some solutions I found close to the official, and the effect was achievable. In terms of memory management, it seems to be unsatisfactory

The specific performance is as follows

First of all, do not use vue mount to element, just simply add a div and remove the div

The main code is as follows, I will start “Allocation instrumentation on timeline” when I click the toast button and end in a few seconds.

import { createApp, defineComponent } from "vue";

const Toast = defineComponent(() => {
  return () => {
    return <div>toast</div>;
  };
});

const toast = () => {
  const div = document.createElement("div");
  document.body.appendChild(div);

  // const toastInstance = createApp(Toast);
  // toastInstance.mount(div);

  // toastInstance.unmount(div);
  document.body.removeChild(div);
};

const App = defineComponent(() => {
  return () => {
    return (
      <div>
        app
        <button onClick={toast}>toast</button>
      </div>
    );
  };
});

const app = createApp(App);
app.mount("#app");

You will find that there is no detached div.

But if I mount this element using vue, even if I unmount this element and remove it, it still exists and takes up memory

import { createApp, defineComponent } from "vue";

const Toast = defineComponent(() => {
  return () => {
    return <div>toast</div>;
  };
});

const toast = () => {
  const div = document.createElement("div");
  document.body.appendChild(div);

  const toastInstance = createApp(Toast);
  toastInstance.mount(div);

  toastInstance.unmount(div);
  document.body.removeChild(div);
};

const App = defineComponent(() => {
  return () => {
    return (
      <div>
        app
        <button onClick={toast}>toast</button>
      </div>
    );
  };
});

const app = createApp(App);
app.mount("#app");

I am not sure if the way I am using is wrong or a problem with vue

I tried this myself.

The Detached HTMLDivElement is being retained by Vue.devtools._buffer (window.__VUE_DEVTOOLS_GLOBAL_HOOK__._buffer is the same thing). That’s effectively an event log for Vue Devtools.

When I switch to a production build of Vue there are no detached elements.

1 Like