Повторно использовать плагин Quasar Dialog с пользовательским компонентом в другом компоненте

Я делаю первые шаги с Quasar.

Я хочу создать модальное окно для повторного использования в формах.

Я использую плагин Dialog и q-layout в пользовательском компоненте.

Однако, когда я использую этот пользовательский компонент в другом компоненте, методы плагина диалога не работают.

Есть ли способ решить эту проблему?

util / modal.js

import { Dialog } from "quasar";

export function ModalWindow(CustomComponent) {

    Dialog.create({
        component:CustomComponent,
        ok: {
            push: true
        },
        cancel: {
            color: 'negative'
        },
        persistent: true
    })
}

modal / ModalWindow.vue (пользовательский компонент):

    <template>
       <q-dialog persistent ref="dialog" @hide="onDialogHide">
         <q-layout view="lhh LpR lff" container style="height: 400px" class="bg-grey-3">       

          <q-toolbar class="bg-primary text-white q-mb-sm">
            <q-toolbar-title>
                <slot name="titelWindow"></slot>
            </q-toolbar-title>
            <q-btn v-close-popup flat round dense icon="close" />
           </q-toolbar>

            <q-form @submit.prevent="submitForm">
                <q-card-section>   
                    <slot></slot>
                </q-card-section>  

                <q-card-actions align="right">
                    <slot name="toolbarBottom"></slot>
                </q-card-actions>
            </q-form>

    </q-layout>
  </q-dialog>
</template>

<script>
export default {
  methods: {
    show () {
      this.$refs.dialog.show()
    },
    hide () {
      this.$refs.dialog.hide()
    },
    onDialogHide () {
      this.$emit('hide')
    }
  }
}
</script>

Вызвать метод ModalWindow на странице:

<script>
    import { ModalWindow } from 'src/util/modal'
    import CustomComponent from "components/modal/MyModalWindow.vue"
    export default {    
        methods: {
            showUWin: function(id) {
                ModalWindow(CustomComponent)
            }
        }
    }
</script>

Пока работает хорошо.

Однако, как я уже сказал, когда я использую этот пользовательский компонент в другом компоненте, методы плагина диалога не работают.

отображать пользовательский компонент в другом компоненте: MyModalForm.vue

<template>
    <MyModalWindow>   
        <!--Dialog's show method doesn't work-->
    </MyModalWindow>  
</template>

<script>
export default {
    name: 'MyModalForm',
    components: {
        'MyModalWindow': require('components/modal/MyModalWindow.vue').default,
    }
}
</script>

Вызвать метод ModalWindow на странице:

<script>
    import { ModalWindow } from 'src/util/modal'
    import CustomComponent from "components/modal/MyModalForm.vue"
    export default {    
        methods: {
            showWin: function(id) {
                ModalWindow(CustomComponent)
            }
        }
    }
</script>

Я захожу на консоль:

[Vue warn]: Error in mounted hook: "TypeError: this.$refs.dialog.show
is not a function"

person josei    schedule 25.10.2019    source источник


Ответы (1)


Недавно я попал в ту же ошибку.

Насколько я понимаю, когда вы используете что-то вроде:

Dialog.create({
  component: CustomComponent,
  ...
})

// or

this.$q.dialog({
  component: CustomComponent
})

CustomComponent должен напрямую реализовывать требуемые методы show / hide / ... в соответствии с документацией.

Таким образом, вы должны повторить в каждом пользовательском компоненте этот код (адаптируя его к правильному «ref», специфичному для вашего компонента):

methods: {
  show () {
    this.$refs.dialog.show()
  },
  hide () {
    this.$refs.dialog.hide()
  },
  onDialogHide () {
    this.$emit('hide')
  }
}

и соответствующим образом распространять события onOk и onCancel.

Например, резюмируя все:

<template>
  <MyModalWindow ref="myModalForm" @ok="onOk" /> 
</template>

<script>
export default {
  name: 'MyModalForm',
  components: {
    'MyModalWindow'
  },
  methods: {
    show() {
      this.$refs.myModalForm.show();
    },
    hide() {
      this.$refs.myModalForm.hide();
    },
    onHide() {
      this.$emit('hide');
    },
    onOk() {
      this.$emit('ok');
      this.hide();
    }
  }
}
</script>

person Matteo Piazza    schedule 15.01.2020
comment
Спасибо, Маттео Пьяцца. - person josei; 16.01.2020
comment
Пожалуйста! Предлагаемое решение выглядит немного уродливым и повторяющимся для меня, но пока я все еще должен прийти к более приятному решению. Может быть, с помощью миксинов ... или нового api композиции ... на случай, если кто-то опубликует здесь обновление. - person Matteo Piazza; 16.01.2020