Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to manually unmount Vue from the dom element components #593

Closed
wuyun1 opened this issue Jan 8, 2020 · 7 comments
Closed

How to manually unmount Vue from the dom element components #593

wuyun1 opened this issue Jan 8, 2020 · 7 comments

Comments

@wuyun1
Copy link

wuyun1 commented Jan 8, 2020

What problem does this feature solve?

  const Vue2ReactWrapper = (vueComponentFactory, componentName) => {
    const ReactPage: React.FC = () => {
      const [loading, setLoading] = useState(true);
      const containerRef = useRef(null);
      useEffect(() => {
        let Vue = require('vue');
        Vue = Vue.default || Vue;
        if (containerRef.current) {
          let vueInstance;
          (async () => {
            let vueApp = await vueComponentFactory();
            vueApp = vueApp.default || vueApp;
            const { createApp } = Vue;
            vueInstance = createApp().mount(vueApp, containerRef.current);
            // vueInstance = new Vue({
            //   render: h => h(vueApp),
            // }).$mount(containerRef.current);
            setLoading(false);
          })();
          return () => {
            if(!vueInstance) return;
            if (vueInstance.$destroy) {
              vueInstance.$destroy();
            } else if (vueInstance.sink) {
              vueInstance.sink.renderer.unmount(vueInstance.$root.vnode);
            }
          }
        }
      }, []);
      ReactPage.displayName = componentName;
      return (
        <div>
          <div ref={containerRef} />
          {loading && <span> 页面加载中 </span>}
        </div>
      );
    }
    return ReactPage;
  }

我希望在 React 元素 unmount 时 ,Vue 元素也能够 unmount。
I hope in the React unmount to elements, also able to unmount to Vue elements.

but now vueInstance.$destroy is undefined...

What does the proposed API look like?

vueInstance.$destroy()

release resources,call beforeUnMount、

@underfin
Copy link
Member

underfin commented Jan 9, 2020

You can do like this.

const app = Vue.createApp()
    app.mount(Root, document.getElementById('app'))

    setTimeout(() => {
       // equal to $destroy
        Vue.render(null, document.getElementById('app') )
    }, 1000)

@underfin
Copy link
Member

underfin commented Jan 9, 2020

Maybe should add some api like unmount.

@wuyun1
Copy link
Author

wuyun1 commented Jan 9, 2020

You can do like this.

const app = Vue.createApp()
    app.mount(Root, document.getElementById('app'))

    setTimeout(() => {
       // equal to $destroy
        Vue.render(null, document.getElementById('app') )
    }, 1000)

用这个方法可以实现 unmount 效果, 成功触发了 vue 组件的 beforeUnmount
谢了。

@yuanjinyong
Copy link

In Vue3, I tried the following code, and it can unmount an component (not the whole app):

      <router-view v-slot="{Component, route}">
        <keep-alive ref="keepAlive"><component :key="route.path" :is="Component" /></keep-alive>
      </router-view>
    onCloseTab(targetName) {
      const route = this.tabRoutes.find(route => targetName === route.params.f_id)
      this.$store.dispatch('removeTab', targetName)

      // 删除组件在keepalive里的cache,参考 pruneCacheEntry 这个方法的逻辑
      const key = route.path
      const keepAliveInstance = this.$refs.keepAlive.$
      const cache = keepAliveInstance.__v_cache
      const vnode = cache.get(key)
      if (vnode) {
        let shapeFlag = vnode.shapeFlag
        if (shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */) {
          shapeFlag -= 256 /* COMPONENT_SHOULD_KEEP_ALIVE */
        }
        if (shapeFlag & 512 /* COMPONENT_KEPT_ALIVE */) {
          shapeFlag -= 512 /* COMPONENT_KEPT_ALIVE */
        }
        vnode.shapeFlag = shapeFlag

        const renderer = keepAliveInstance.ctx.renderer
        renderer.um(vnode, keepAliveInstance, keepAliveInstance.suspense)

        cache.delete(key)
      }
    }

this.$.ctx.renderer.um(vnode, keepAliveInstance, keepAliveInstance.suspense)

@zs-g
Copy link

zs-g commented Nov 2, 2021

在 Vue3 中,我尝试了以下代码,它可以卸载一个组件(不是整个应用程序):

      <router-view v-slot="{Component, route}">
        <keep-alive ref="keepAlive"><component :key="route.path" :is="Component" /></keep-alive>
      </router-view>
    onCloseTab(targetName) {
      const route = this.tabRoutes.find(route => targetName === route.params.f_id)
      this.$store.dispatch('removeTab', targetName)

      // 删除组件在keepalive里的cache,参考 pruneCacheEntry 这个方法的逻辑
      const key = route.path
      const keepAliveInstance = this.$refs.keepAlive.$
      const cache = keepAliveInstance.__v_cache
      const vnode = cache.get(key)
      if (vnode) {
        let shapeFlag = vnode.shapeFlag
        if (shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */) {
          shapeFlag -= 256 /* COMPONENT_SHOULD_KEEP_ALIVE */
        }
        if (shapeFlag & 512 /* COMPONENT_KEPT_ALIVE */) {
          shapeFlag -= 512 /* COMPONENT_KEPT_ALIVE */
        }
        vnode.shapeFlag = shapeFlag

        const renderer = keepAliveInstance.ctx.renderer
        renderer.um(vnode, keepAliveInstance, keepAliveInstance.suspense)

        cache.delete(key)
      }
    }

this.$.ctx.renderer.um(vnode, keepAliveInstance, keepAliveInstance.suspense)

After the project is packaged, keepAliveInstance.__v_cache does not get the value

1635845746(1)

@mrzhxping
Copy link

In Vue3, I tried the following code, and it can unmount an component (not the whole app):

      <router-view v-slot="{Component, route}">
        <keep-alive ref="keepAlive"><component :key="route.path" :is="Component" /></keep-alive>
      </router-view>
    onCloseTab(targetName) {
      const route = this.tabRoutes.find(route => targetName === route.params.f_id)
      this.$store.dispatch('removeTab', targetName)

      // 删除组件在keepalive里的cache,参考 pruneCacheEntry 这个方法的逻辑
      const key = route.path
      const keepAliveInstance = this.$refs.keepAlive.$
      const cache = keepAliveInstance.__v_cache
      const vnode = cache.get(key)
      if (vnode) {
        let shapeFlag = vnode.shapeFlag
        if (shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */) {
          shapeFlag -= 256 /* COMPONENT_SHOULD_KEEP_ALIVE */
        }
        if (shapeFlag & 512 /* COMPONENT_KEPT_ALIVE */) {
          shapeFlag -= 512 /* COMPONENT_KEPT_ALIVE */
        }
        vnode.shapeFlag = shapeFlag

        const renderer = keepAliveInstance.ctx.renderer
        renderer.um(vnode, keepAliveInstance, keepAliveInstance.suspense)

        cache.delete(key)
      }
    }

this.$.ctx.renderer.um(vnode, keepAliveInstance, keepAliveInstance.suspense)

after build not find __v_cache

@wisetc
Copy link

wisetc commented Nov 18, 2021

vue2 in nuxt, 为何调用根结点的 vm.$destroy() 方法只能销毁vm, 却不能从DOM中移除mount 的DOM?

@github-actions github-actions bot locked and limited conversation to collaborators Oct 7, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants