ダイアログ (Dialog): v-dialog
ボタンなどを押すと、画面内にポップアップするウィンドウを出すことができるコンポーネントです。
基本
ダイアログは、構成要素としてダイアログを表示するためにトリガーになる要素(ボタン v-btn
など)と、ダイアログの実態になる要素(v-sheet
、v-card
など)を必要とします。
<template>
<v-container >
<v-btn
color="primary"
>
Open Dialog
<v-dialog
v-model="dialog"
activator="parent"
>
<v-sheet>
<v-sheet class="my-2 mx-5">
<h2>Dialog</h2>
<p class="my-4">
Please confirm information!
</p>
<v-btn color="primary" block @click="dialog = false">Close</v-btn>
</v-sheet>
</v-sheet>
</v-dialog>
</v-btn>
</v-container>
</template>
<script>
export default {
data () {
return {
dialog: false,
}
},
}
</script>
ダイアログの要素は実態をもっておらず、ボタンと表示される実態(上の例では v-card
)を結合して、ダイアログとして機能させる役割をします。
トリガーとなるボタンを親要素とし、その子要素として v-doalog
を設置し、さらにその子要素として、ダイアログの実体になる v-card
を配置します。
ダイアログは、v-model
に指定された変数が true
のときに開き、false
のときに閉じます。上の例では v-btn
を押すと閉じます。
なお、デフォルトではダイアログの外側をクリックしてもダイアログは閉じます。ダイアログの外をクリックしたときに閉じないようにするには、persistent
prop を使います。これを使うと、ボタンを押したときしかダイアログは閉じなくなります。
<template>
<v-container >
<v-btn
color="primary"
>
Open Dialog
<v-dialog
v-model="dialog"
persistent
activator="parent"
>
<v-sheet>
<v-sheet class="my-2 mx-5">
<h2>Dialog</h2>
<p class="my-4">
Please confirm information!
</p>
<v-btn color="primary" block @click="dialog = false">Close</v-btn>
</v-sheet>
</v-sheet>
</v-dialog>
</v-btn>
</v-container>
</template>
<script>
export default {
data () {
return {
dialog: false,
}
},
}
</script>
v-slot:activator を使う方法
ダイアログの構成方法は v-menu
とよく似ています。v-menu
と同様に、v-slot:activator
を使って下記のように書くこともできます。
動作や見かけは、前述の例とまったく同じになります。
<template>
<v-container >
<v-dialog
v-model="dialog"
activator="parent"
>
<template v-slot:activator="{ props }">
<v-btn color="primary" v-bind="props"> Open Dialog</v-btn>
</template>
<v-sheet>
<v-sheet class="my-2 mx-5">
<h2>Dialog</h2>
<p class="my-4">
Please confirm information!
</p>
<v-btn color="primary" block @click="dialog = false">Close</v-btn>
</v-sheet>
</v-sheet>
</v-dialog>
</v-container>
</template>
<script>
export default {
data () {
return {
dialog: false,
}
},
}
</script>
この方法でダイアログを作る場合、デフォルトスロット v-slot="{ isActivate }"
を使うとダイアログをアクティベート(表示状態に)するたの変数を <script>
セクションで定義しなくてすみます。
<template>
<v-container >
<v-dialog>
<template v-slot:activator="{ props }">
<v-btn color="primary" v-bind="props"> Open Dialog</v-btn>
</template>
<template v-slot="{ isActivate }">
<v-sheet>
<v-sheet class="my-2 mx-5">
<h2>Dialog</h2>
<p class="my-4">
Please confirm information!
</p>
<v-btn color="primary" block @click="isActivate.value = false">Close</v-btn>
</v-sheet>
</v-sheet>
</template>
</v-dialog>
</v-container>
</template>
ダイアログの操作として「閉じる」以外の操作がないような、シンプルなダイアログの場合にはこの方法が便利です。
v-model でダイアログを強制的に開く方法
v-btn
(トリガー) と v-dialog
の間に親子関係がなく、なおかつ v-slot
使わなくても、v-btn
を押したときに v-dialog
の v-model
に設定した変数を true
にする処理を書けば、ダイアログは開きます。
ただし v-slot:activator
を使う時とはダイアログの開き方が変わります。
<template>
<v-container >
<v-btn color="primary" @click="dialog = true"> Open Dialog</v-btn>
<v-dialog
v-model="dialog"
>
<v-sheet>
<v-sheet class="my-2 mx-5">
<h2>Dialog</h2>
<p class="my-4">
Please confirm information!
</p>
<v-btn color="primary" block @click="dialog = false">Close</v-btn>
</v-sheet>
</v-sheet>
</v-dialog>
</v-container>
</template>
<script>
export default {
data () {
return {
dialog: false,
}
},
}
</script>
このように、v-slot:activator
や activator="parent"
で指定されていないボタンを使ってダイアログを開くと、ダイアログがボタンの位置から開くアニメーションになりません。
ダイアログが開くときに、押したボタンからダイアログがポップアップしてくるアニメーションを使うときは、前述のように v-slot:activator
や activator="parent"
を使う必要があります。
ポップアップ時のアニメーションを設定する
transition
prop を使うと、ダイアログのポップアップ時のアニメーションを指定できます。デフォルトは dialog-transition
です。
<template>
<v-container >
<v-btn color="primary" @click="dialog = true"> Open Dialog</v-btn>
<v-dialog
v-model="dialog"
transition="dialog-top-transition"
>
<v-sheet>
<v-sheet class="my-2 mx-5">
<h2>Dialog</h2>
<p class="my-4">
Please confirm information!
</p>
<v-btn color="primary" block @click="dialog = false">Close</v-btn>
</v-sheet>
</v-sheet>
</v-dialog>
</v-container>
</template>
<script>
export default {
data () {
return {
dialog: false,
}
},
}
</script>
設定可能な transition の一覧は下記にあります。
transition を指定するときは、上記ページにある transition のクラス名の先頭の v-
を削除します。たとえば、v-slide-x-transition
は transition="slide-x-transition"
のように設定します。
なお、なぜか上記ページのリストには含まれていませんが、下記の transition も使用できます。
dialog-top-transition
dialog-bottom-transition
ダイアログに複数の機能をもつボタンを設置する
ダイアログに複数のボタンを設置して、押したボタンによって違う挙動をさせることもできます。下の例では、OK ボタンを押すと数字をひとつ増やしてダイアログを閉じ、Cancel を押したときは数字を増やさずダイアログを閉じます。
<template>
<v-container>
<v-btn
@click="dialog = true"
color="primary"
>
Open Dialog
</v-btn>
<h2>
{{counter}}
</h2>
<v-dialog
v-model="dialog"
>
<v-sheet>
<v-sheet class="my-2 mx-5">
<h2>Dialog!</h2>
<p class="my-4">
数字を1増やします。数字を1増やします。
</p>
<div class="d-flex justify-end my-2">
<v-btn class="mx-2" color="primary" @click="click(true)">OK</v-btn>
<v-btn class="mx-2" color="secondary" @click="click(false)">Cancel</v-btn>
</div>
</v-sheet>
</v-sheet>
</v-dialog>
</v-container>
</template>
<script>
export default {
data () {
return {
dialog: false,
counter: 0,
}
},
methods: {
click(flag){
if ( flag ){
this.counter ++;
}
this.dialog = false;
}
}
}
</script>
ボタンを押さずに、ダイアログの外側をクリックしてダイアログを閉じたときは、単純にダイアログを閉じる以外の処理は行われません(上の例では this.dialog=false
とした時と同じ動作になる)。
ダイアログの内部をスクロール可能にする
ダイアログに表示する情報量が多いときに、ダイアログ内をスクロールできるようにしたいことがあります。そのようなときは scrollable
prop を使います。
<template>
<v-container >
<v-btn
color="primary"
>
Open Dialog
<v-dialog
v-model="dialog"
scrollable
activator="parent"
>
<v-sheet class="my-2 mx-5 pa-3" height="50vh">
<v-list>
<v-list-item
v-for="n in 20"
:key="n"
:value="n"
:title="'Item ' + n"
></v-list-item>
</v-list>
<v-btn color="primary" block @click="dialog = false">Close</v-btn>
</v-sheet>
</v-dialog>
</v-btn>
</v-container>
</template>
<script>
export default {
data () {
return {
dialog: false,
}
},
}
</script>
入れ子のダイアログ
ダイアログは入れ子にすることもできます。
<template>
<v-container >
<v-btn
color="primary"
>
Open Dialog
<v-dialog
v-model="dialog1"
activator="parent"
>
<v-sheet class="my-2 mx-5 pa-3">
<div class="mx-3 my-3">Dialog 1</div>
<v-btn color="primary" class="mx-3">Open Dialog
<v-dialog
v-model="dialog2"
activator="parent"
>
<v-sheet class="my-2 mx-5 pa-3">
<div class="mx-3 my-3">Dialog 2</div>
<v-btn color="secondary" @click="dialog2 = false">Close</v-btn>
</v-sheet>
</v-dialog>
</v-btn>
<v-btn color="secondary" @click="dialog1 = false">Close</v-btn>
</v-sheet>
</v-dialog>
</v-btn>
</v-container>
</template>
<script>
export default {
data () {
return {
dialog1: false,
dialog2: false
}
},
}
</script>
上の例では2つのダイアログをネストしていますが、さらに多くのダイアログをネストすることも可能です。
その他
詳しくは、公式ドキュメントを参照してください。