Vue.js で同期的なダイアログ表示を行う
25019 ワード
概要
Vue.js において await
で boolean
の結果を受け取れるようなダイアログ表示をプログラムから行います。
ダイアログで OK またはキャンセルが押されるまで処理をストップします。
非効率な処理が含まれます。導入の際は注意事項をご確認ください。
開発環境
- Vue 2.6.11
- Vuetify 2.6.0
実装
呼び出し側
HelloWorld.vue
<template>
<v-container>
<v-row class="text-center">
<v-col cols="12">
<v-btn elevation="2" @click.stop="onClick">Show Alert</v-btn>
</v-col>
</v-row>
</v-container>
</template>
<script lang="ts">
import Vue from "vue";
import Component from "vue-class-component";
import { confirm } from "./AsyncDialog.vue";
@Component
export default class HelloWorld extends Vue {
onClick(): void {
(async () => {
const answer = await confirm("実行します。よろしいですか?");
console.log(`answer: ${answer}`);
})();
}
}
</script>
ダイアログ側
AsyncDialog.vue
<template>
<v-dialog v-model="dialog" width="500" @click:outside="cancel">
<v-card>
<v-card-text class="pa-4">
{{ message }}
</v-card-text>
<v-divider></v-divider>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn @click="ok"> OK </v-btn>
<v-btn @click="cancel"> キャンセル </v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<script lang="ts">
import Vue from "vue";
import vuetify from "@/plugins/vuetify";
import Component from "vue-class-component";
import { Prop } from "vue-property-decorator";
@Component
export default class AsyncDialog extends Vue {
@Prop({ required: true }) message!: string;
@Prop({ required: true }) okAction!: () => void;
@Prop({ required: true }) cancelAction!: () => void;
dialog = false;
ok(): void {
this.okAction();
this.close();
}
cancel(): void {
this.cancelAction();
this.close();
}
created(): void {
this.$mount();
document.body.appendChild(this.$el);
this.dialog = true;
}
close(): void {
this.dialog = false;
setTimeout(() => {
if (document.body.contains(this.$el)) document.body.removeChild(this.$el);
this.$destroy();
}, 200);
}
}
export const confirm = async (message: string): Promise<boolean> => {
return new Promise<boolean>((resolve) => {
const VM = Vue.extend(AsyncDialog);
new VM({
vuetify,
parent: this,
propsData: {
message,
okAction: () => resolve(true),
cancelAction: () => resolve(false),
},
});
}).catch((err) => {
throw err;
});
};
</script>
注意事項
ダイアログ表示の度にインスタンスを生成しているため、処理としては非効率です。
本来であれば各ページのコンポーネント内にダイアログを定義することになると思います。
あくまでも、何らかの理由でそれができない場合の対応策の一つとしてお考えください。
参考
Author And Source
この問題について(Vue.js で同期的なダイアログ表示を行う), 我々は、より多くの情報をここで見つけました https://zenn.dev/tshuto/articles/bd236f2f49b0d1著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Collection and Share based on the CC protocol