umut can topal
umut can topal

Reputation: 11

Vuejs 3 how to get component instance properties programmatically

I have function which is written in vue 2 and I need to modifiy for vue 3. there is component named Modal which is a confirmation box with lots of props and option. in codebase it call showPrompt function programmatically many place and it basicly creates a new component instance and adds listeners for emits with $on method and mutates isVisible data to true to show component. Vue.component is changed with app.component and it's not returns registered component instance. and I cannot use $on, $destroy methods etc. how can i modifiy this function for version 3.

import Modal from '@/layouts/Modal.vue'

export function showPrompt (props: object) {
  const Klass = Vue.component('promptModal', Modal)
  const propsData = {
    positiveButtonColor: 'error',
    showPositiveButton: true,
    contentSlotPaddingClass: 'pa-0',
    ...props
  }
  // FIXME: Type Issue
  // @ts-ignore
  if (get(propsData, 'positiveButtonText', '') === 'Yes') {
    set(propsData, 'positiveButtonColor', 'primary')
  }
  const instance = new Klass({
    vuetify,
    i18n,
    propsData: propsData
  })
  each(get(propsData, 'listeners'), (listener, key) => {
    // FIXME: Type Issue
    // @ts-ignore
    instance.$on(key, listener)
  })
  instance.$on('dialogObserverCallback', (value: boolean) => {
    if (!value) {
      setTimeout(() => {
        instance.$destroy()
      }, 1000)
    }
  })
  instance.$mount()
  set(instance, 'isVisible', true)
  return instance
}

I tried defineExpose to access component data but couldn't make progres

Upvotes: 1

Views: 585

Answers (1)

gear4
gear4

Reputation: 844

This is a matter of VueJS internals I believe - and also not a great way to engineer something like multiple components.


What you're looking to replace requires decent knowledge of how VueJS 3 works. The following is an example of how it works, but note that the component context (stores, plugins, directives...) will be lost:

import { defineComponent, createApp } from 'vue';
import Modal from '@/layouts/Modal.vue';

const modalView = defineComponent({
    extends: Modal
})

const div = document.createElement('div');
this.$refs.container.appendChild(div);
createApp(modalView).mount(div)

Upvotes: 1

Related Questions