Как программно запустить диалог Vuetify и дождаться ответа - PullRequest
0 голосов
/ 07 мая 2019

Я довольно новичок в Vue.js и Vuetify (использовал AngularJS в течение нескольких лет, но наша компания переходит на Vue.js). То, что я пытаюсь сделать, - это когда пользователь нажимает на кнопку «войти», он выполняет некоторые проверки (то есть имя пользователя не может быть пустым) и запускает диалог Vuetify, чтобы предупредить пользователя. Я знаю, что Vuetify имеет некоторые встроенные средства проверки, но ищет что-то более надежное, где я могу ждать ответа (т.е. когда мне нужно ждать чего-то вроде, могу ли я использовать вашу историю / местоположение).

В основном хочу сделать:

if (!userName){
    userName = await mbox('You must Enter your Username');
    return
}

OR

var mProceed = await mbox('Can we use your location for awesome stuff?');

где mbox (простое всплывающее окно сообщения) - это функция, которая возвращает обещание, программно загружает компонент vue, добавляет его в dom и ожидает ответа.

Exmple Dialog Screen Shot

т.е.

async function mbox (mText) {
    // load dialog component here and set message passed in
    // How Do I load the template / wait for it?
    return dialogResult

}

Компонент Vue будет выглядеть примерно так (с заголовками кнопок и текстом, являющимся переменными, я передаю свою функцию mbox):

<template>
<v-layout row justify-center>
<v-dialog
  v-model="dialog"
  max-width="290"
>
  <v-card>
    <v-card-title class="headline">Use Google's location service?</v-card-title>

    <v-card-text>
      Let Google help apps determine location. This means sending anonymous location data to Google, even when no apps are running.
    </v-card-text>

    <v-card-actions>
      <v-spacer></v-spacer>

      <v-btn
        color="green darken-1"
        flat="flat"
        @click="dialog = false"
      >
        Disagree
      </v-btn>

      <v-btn
        color="green darken-1"
        flat="flat"
        @click="dialog = false"
      >
        Agree
      </v-btn>
    </v-card-actions>
  </v-card>
</v-dialog>
</v-layout>
</template>

Я нормально редактирую шаблон / добавляю скрипт для компонента vue. Я просто не уверен, как вызвать его через метод, который возвращает обещание и ждет ответа?

1 Ответ

1 голос
/ 09 мая 2019

Закончилось решение проблемы следующим образом:

У меня есть метод mbox (возвращает обещание), который создает экземпляр моего компонента, добавляет его в DOM, а затем наблюдает за свойством этого компонентазнать, какой вариант выбрал пользователь.Выполняет обещание, как только пользователь выбрал опцию

Мой метод mbox:

import MBOX from './components/mbox.vue';
import _Vue from 'vue';
export default {

mbox(mText, mTitle, mBtnCap1, mBtnCap2, mBtnCap3){
    return new Promise(async (resolve, reject) => {
        if (!mTitle){
            mTitle = 'My Title';
        }
        if (!mBtnCap1){
            mBtnCap1 = 'OK';
        }

        // I'm combining a bunch of stuff to make this work.
        // First, create the vue component
        var mboxInstance = _Vue.extend(MBOX); // mbox component, imported at top of Sublib
        var oComponent = new mboxInstance({ 
            propsData: { 
                msg: mText, 
                title: mTitle, 
                btnCap1: mBtnCap1, 
                btnCap2: mBtnCap2, 
                btnCap3: mBtnCap3,
                retval: 0
                }
        }).$mount();

        // now add it to the DOM
        var oEl = document.getElementById('app').appendChild(oComponent.$el);

        // NOTE: couldn't get it to work without adding a 'button' to activate it
        // progrmatically click it and make the button invisible
        // document.getElementById('mbox_btn_launch').click();
        var oLuanchBtn = document.getElementById('mbox_btn_launch');
        oLuanchBtn.style.visibility = 'hidden';
        oLuanchBtn.click();

        // Add a listener so we can get the value and return it
        oComponent.$watch('retval', function(newVal, oldVal){
            // this is triggered when they chose an option
            // Delete the component / element now that I'm done
            oEl.remove();
            resolve(Number(newVal));
        })
    }); // promise
}, // mbox
}

И мой компонент MBOX:

<template>
<v-dialog max-width="290" persistent v-if="showMbox">
    <template v-slot:activator="{on}">
        <v-btn id="mbox_btn_launch" v-on="on">
            Test
        </v-btn>
    </template>
    <v-card>
        <v-card-title>{{title}}</v-card-title>
        <v-card-text>{{msg}}</v-card-text>
        <v-card-actions>
            <v-spacer></v-spacer>
            <v-btn v-if="btnCap1" @click="btnClicked('1')">{{btnCap1}}</v-btn>
            <v-btn v-if="btnCap2" @click="btnClicked('2')">{{btnCap2}}</v-btn>
            <v-btn v-if="btnCap3" @click="btnClicked('3')">{{btnCap3}}</v-btn>
        </v-card-actions>
    </v-card>
</v-dialog>
</template>
<script>
export default {
    name: 'mbox',
    data: () => ({
        showMbox: true    
    }),
    props: [
        // these can be passed in, the 'data' stuff can't
        'msg',
        'title',
        'btnCap1',
        'btnCap2',
        'btnCap3',
        'retval' // watches this so we know when they clicked something
    ],
    created(){    
        this.showMbox = true;
    }, 
    methods: {
    btnClicked: function(mBtnClicked){
        // mBtnClicked = Char. Has to be a character in order for it to pass it in. Not sure why, numerics didn't work
        mBtnClicked = Number(mBtnClicked);
        this.retval = mBtnClicked; // watcher in Sublib will detect this value has changed
        this.showMbox = false;
    } // btnClicked
} // methods
} // export default
</script>
<style scoped>
</style>

Затем я могу назвать его так:

var mChoice = await mbox('What do you want to do?', 'Title', 'Option 1', 'Option 2');

или для простого запроса проверки:

if (!userName){
    mbox('You must enter a username');
    return;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...