Home > Software engineering >  How to call a dynamically created/ mounted global component in Quasar2 (Vue3 - Options API)
How to call a dynamically created/ mounted global component in Quasar2 (Vue3 - Options API)

Time:10-11

I am not exactly sure how to phrase this question. I am attempting to port one of my Vue2 global components to Vue3 (Options API). In short, I am trying to mount a custom dialog component globally, i.e. creating it in the boot folder (And have added it to quasar.conf.js boot section) and then be able to call it in any of my Vue files in my project, without having to import it in every vue file i.e. similar to this.$axios.

The original plug-ins file using an earlier version of Vue was similar to

import Vue from 'vue';
import dialog from '@/components/dialog.vue';

export default ({ app }, inject) => {
    const $dialog = Vue.extend( dialog );
    const vm = new $dialog({ i18n: app.i18n }).$mount();
    document.body.appendChild(vm.$el);

    inject('dialog', vm);
};

I found my answer to work around the deprecation of Vue.extend here and used a component that implements the suggested solution by pearofducks on github, which appears to mount the component correctly.

Back to my boot file

boot_dialog.js

import { boot } from 'quasar/wrappers'
import { mount } from 'mount-vue-component'
import customDialog from '../~global/scripts/debug/debug'

export default boot( async ({ app }) => {

  const element = document.createElement('div');
  element.setAttribute('id','modal-dialog-div');
  document.body.appendChild(element);
  const { vNode, destroy, el } = mount(customDialog, { app, element, props: { i18n: app.i18n }});
  app.config.globalProperties.$dialog = customDialog;
  // ^^^ Believe the error is here
});

I know that the component gets mounted as on mount in debug.vue I call the this.show() which displays the q-dialog correctly.

devug.vue

<template>
  <q-dialog v-model="alert">
    <q-card>
      <q-card-section>
        <div class="text-h6">Alert test</div>
      </q-card-section>

      <q-card-section class="q-pt-none">
        Lorem ipsum dolor sit amet
      </q-card-section>

      <q-card-actions align="right">
        <q-btn flat label="OK" color="primary" v-close-popup />
      </q-card-actions>
    </q-card>
  </q-dialog>
</template>

<script>
export default {
  data () {
    return {
      alert: false,
    }
  },
  methods: {
    show (params) {
      console.log('Show method called',params);
       this.alert = true;
    },
  },
  mounted() {
    this.show('Parameters');
  }
};
</script>

But calling this.$dialog.show('A sample parameter') in any of my main project vue files causes an error. How do I work back from the vNode const to an actual component which I can call in any of the projects vue files ?

CodePudding user response:

I think what you want is a custom plugin: https://v3.vuejs.org/guide/plugins.html#writing-a-plugin

  • Related