vue.js - 如何以编程方式销毁 Vue3 组件实例?

标签 vue.js vuejs3

我正在开发一个 Vue3 插件,该插件可以在用户对 UI 执行某些操作后生成一个 toast。

我使用 createVNode 创建了 toast 并进行渲染,效果非常好。 2500 毫秒后,我希望 Toast 从 UI 中消失,并且 Vue 组件 Toast 被销毁。但是我注意到 render(null,container) 或 document.body.removeChild(container) 实际上确实从 UI 中删除了 Toast,并从 DOM 中删除了 Toast 节点,它不会破坏 Toast 组件实例。我担心的是,经过几十个 Toast 后,内存会增加,而不会从旧的 Toast 中清除。

Vue3 中有没有办法以编程方式销毁组件?

import { createVNode, Plugin, render } from 'vue'
import Alert from './Alert.vue'

const plugin: Plugin = {
    // eslint-disable-next-line
    install(app, options) {

        const toast = {
            show(message: string) {

                const container = document.createElement('div')
                document.body.appendChild(container)

                const toastVNode = createVNode(
                    Alert,
                    { message: message },
                    null
                )

                render(toastVNode, container)

                setTimeout(function () {
                    render(null, container)
                    document.body.removeChild(container)
                }, 2500);

            }
        }

        app.provide("$Toast", toast);
    }
}

export default plugin

最佳答案

Alert 组件应该接受 period/closeDelay 作为 prop,并在其安装的钩子(Hook)上调用 setTimeout 处理程序并发出一些自定义事件,我们将其称为 closeEvent 。如果使用 vue2,请使用 this.$emit("closeEvent");如果使用 vue 3,请使用 context.$emit("closeEvent")。如果 Alert 是来自第三方 ui 库的组件,那么您可以围绕它创建一个包装器组件

您的函数现在应该如下所示

const container = document.createElement('div')

document.body.appendChild(container)

let toastApp = createApp(Alert,{closeDelay:2500,message:message },null)

//Notice I create a listener for closeEvent with toastApp.props.onCloseEvent before

toastApp.props.onCloseEvent=()=>{
 render(null,container);
}

//Made this as the last call
render(toastApp,container);

在您的 Alert 组件上,如果使用 vue 3,您的代码应该类似于以下内容

<script> 
 export default {
 props:["message","closeDelay"],
 emits: ["closeEvent"],
 setup(props,context){
 onMounted(()=>{
    setTimeout(() => {
    context.emit("closeEvent")
   }, props.closeDelay)
   })
  }
 }
</script>

关于vue.js - 如何以编程方式销毁 Vue3 组件实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67690932/

相关文章:

javascript - 为什么这个数组不为空?

html - v-on :click in component not working

vue.js - 将 "detect click outside"自定义指令从 Vue 2 迁移到 Vue 3

typescript - this.$store 在 Vue 3 中未定义,带有 Vuex 4 商店和路由器

javascript - 如何访问 Vuejs 设置函数内传递的 props(Composition API)

javascript - 这是 typescript 功能吗?

css - 使用vue素材搭建服务描述页面,无法让Text和Image叠加

javascript - 仅切换 Accordion 点击 vue.js

javascript - Vuex 状态和 vue-router

javascript - 用 Vite 替换 Vuejs 3 中的 require 用于图像数组