我有一个用于常见场景的Vue 2模式:以编程方式创建一个实例,以便在模板外部的动态内容上打开Modal/Dialog/Lightbox。
在Vue 2中,我发现了这样的模式:
// DialogService.js
export default {
alert(text) {
const DialogClass = Vue.extend(DialogComponentDef);
let dialog = new DialogClass({ propsData: { text } });
dialog.$on('close', () => {
dialog.$destroy();
dialog.$el.remove();
dialog = null;
});
// mount the dynamic dialog component in the page
const mountEl = document.createElement('div');
document.body.appendChild(mountEl);
dialog.$mount(mountEl);
},
};
知道Vue.extends
,$on
和$destroy
已经不存在了,我怎么才能在Vue 3中实现这一点呢?您可以查看clicking here提供的DialogService.js的完整示例。
发布于 2021-10-29 18:03:49
以下是如何在Vue 3中处理createApp
,但上下文(存储、插件、指令...)将不会被保留。
// DialogService.js
import { createApp } from 'vue';
export default {
alert(text) {
const mountEl = document.createElement('div');
document.body.appendChild(mountEl);
const dialog = createApp({ extends: DialogComponentDef }, {
// props
text,
// events are passed as props here with on[EventName]
onClose() {
mountEl.parentNode.remvoeChild(mountEl);
dialog.unmount();
dialog = null;
},
});
dialog.mount(mountEl);
},
};
为了保持上下文,在h
和render
Vue方法中可以看到更复杂的东西:https://github.com/vuejs/vue-next/issues/2097#issuecomment-709860132
发布于 2021-10-27 06:57:13
Vue 3没有提供通用的事件总线。它可以被像mitt
或eventemitter3
这样的轻量级第三方替代方案所取代。
组件可以使用teleport安装在应用程序元素层次结构之外。这之前已经在Vue 2和第三方portal-vue
库中可用。模态和其他屏幕UI元素是它的常见用例
<teleport to="body">
<DialogComponent ref="dialog" @close="console.log('just a notification')">
Some markup that cannot be easily passed as dialog.value.show('text')
</DialogComponent>
</teleport>
其中DialogComponent
控制自己的可见性,不需要像原始代码片段那样显式卸载。父级卸载时会自动执行清理:
<teleport to="body">
<div v-if="dialogState">
<slot>{{dialogText}}</slot>
</div>
</teleport>
和
let dialogState = ref(false);
let dialogText = ref('');
let show = (text) => {
dialogText.value = text;
dialogState.value = true;
} ;
...
return { show };
对于更复杂的场景,需要管理多个实例,或者需要在业务逻辑的组件外部访问show
,则需要在组件层次结构的顶层挂载一个远程端口。在这种情况下,可以通过应用程序传递的事件总线实例可用于交互。
https://stackoverflow.com/questions/69732406
复制相似问题