Answer a question

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.

Answers

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.remvoeChild(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

Logo

Vue社区为您提供最前沿的新闻资讯和知识内容

更多推荐