I have a Vue 2 pattern I was using for a common scenario: programmatically creating an instance to open a Modal/Dialog/Lightbox on dynamic content outside of a template.
In Vue 2, I found this pattern:
// 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);
},
};
How can I acheive this in Vue 3, knowing Vue.extends
, $on
& $destroy
do not exist anymore?
You can see a full example of the DialogService.js by clicking here.
Here's how to do with createApp
in Vue 3, but the context (stores, plugins, directives...) will not be kept.
// 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.removeChild(mountEl);
dialog.unmount();
dialog = null;
},
});
dialog.mount(mountEl);
},
};
To keep the context, there's something more complicated that can be seen here with h
and render
Vue methods : https://github.com/vuejs/vue-next/issues/2097#issuecomment-709860132