Vuetifyのv-dialog
を使ってダイアログのコンポーネントを作成してましたが、なぜかダイアログが表示できずハマったため、備忘録としてまとめます。
- Vue.js 3.3.4
- Vuetify 3.4.4
目次
問題
以下のコードのように、v-if
ディレクティブを用いてv-dialog
の表示・非表示を制御しようとしていました。
<script setup lang="ts">
import { ref } from 'vue';
const isActive = ref(false);
const openDialog = (): void => {
isActive.value = true;
};
const closeDialog = (): void => {
isActive.value = false;
};
</script>
<template>
<v-app>
<v-container>
<v-btn @click="openDialog">ダイアログを開く</v-btn>
<!-- v-if で表示・非表示を切り替えたいが上手くいかない -->
<v-dialog v-if="isActive">
<v-card>
<v-card-title>ダイアログ</v-card-title>
<v-card-text>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Illo distinctio non quo officiis praesentium
provident, iste deleniti culpa mollitia ab modi eum qui animi ipsum. Voluptates mollitia fugiat sed eius?
</p>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn @click="closeDialog">閉じる</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</v-container>
</v-app>
</template>
「ダイアログを開く」ボタンを押すとVue DevTools上では確かにVDialog
コンポーネントが存在しているのですが、なぜかサイズが「0 × 0」となってしまい、ダイアログが表示されない状況でした。
解決方法
v-if
ではなくv-model
を使うことでダイアログが狙い通りに表示されるようになりました。
<script setup lang="ts">
import { ref } from 'vue';
const isActive = ref(false);
const openDialog = (): void => {
isActive.value = true;
};
const closeDialog = (): void => {
isActive.value = false;
};
</script>
<template>
<v-app>
<v-container>
<v-btn @click="openDialog">ダイアログを開く</v-btn>
<!-- v-if から v-model に変更 -->
<v-dialog v-model="isActive" width="500">
<v-card>
<v-card-title>ダイアログ</v-card-title>
<v-card-text>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Illo distinctio non quo officiis praesentium
provident, iste deleniti culpa mollitia ab modi eum qui animi ipsum. Voluptates mollitia fugiat sed eius?
</p>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn @click="closeDialog">閉じる</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</v-container>
</v-app>
</template>
すると綺麗に表示されました!
公式ドキュメントからの補足
Vuetifyの公式ドキュメントを見たところ、以下のコードのようにv-dialog
コンポーネントの中に、ボタンもダイアログも含めるのが正しい使い方のようです。
<!-- <script> は不要 -->
<template>
<v-app>
<v-container>
<v-dialog width="500">
<!-- v-btn コンポーネントも v-dialog に含む -->
<template v-slot:activator="{ props }">
<v-btn v-bind="props" text="ダイアログを開く"> </v-btn>
</template>
<!-- isActive はVuetify側が用意している変数 -->
<template v-slot:default="{ isActive }">
<v-card title="ダイアログ">
<v-card-text>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et
dolore magna aliqua.
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn text="閉じる" @click="isActive.value = false"></v-btn>
</v-card-actions>
</v-card>
</template>
</v-dialog>
</v-container>
</v-app>
</template>
まとめ
Vuetifyのv-dialog
コンポーネントを使う際はv-if
ではなくv-model
で表示・非表示を切り替えること、そもそもv-dialog
の中にボタンもダイアログも含めるのが公式の使い方であることを学びました。
コメント