我正在开发一个 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/