Dialog ダイアログ
モーダルダイアログコンポーネント。重要な情報の表示や操作の確認に使用します。
基本的な使い方
基本的な使い方
vue
<script setup lang="ts">
import { ref } from 'vue'
import { LhButton, LhDialog } from '@lh-ui/vue3'
const dialogVisible1 = ref(false)
</script>
<template>
<!-- 基本的な使い方 -->
<LhButton @click="dialogVisible1 = true">ダイアログを開く</LhButton>
<LhDialog v-model="dialogVisible1" title="通知">
<p>これはダイアログの内容です</p>
<template #footer>
<LhButton @click="dialogVisible1 = false">キャンセル</LhButton>
<LhButton type="primary" @click="dialogVisible1 = false">OK</LhButton>
</template>
</LhDialog>
</template>vue
<script>
import { LhButton, LhDialog } from '@lh-ui/vue3'
export default {
components: { LhButton, LhDialog },
data() {
return {
dialogVisible1: false
}
}
}
</script>
<template>
<!-- 基本的な使い方 -->
<LhButton @click="dialogVisible1 = true">ダイアログを開く</LhButton>
<LhDialog v-model="dialogVisible1" title="通知">
<p>これはダイアログの内容です</p>
<template #footer>
<LhButton @click="dialogVisible1 = false">キャンセル</LhButton>
<LhButton type="primary" @click="dialogVisible1 = false">OK</LhButton>
</template>
</LhDialog>
</template>幅・高さのカスタマイズ
幅のカスタマイズ
vue
<script setup lang="ts">
import { ref } from 'vue'
import { LhButton, LhDialog } from '@lh-ui/vue3'
const dialogVisible2 = ref(false)
</script>
<template>
<!-- 幅・高さのカスタマイズ -->
<LhButton @click="dialogVisible2 = true">大きなダイアログを開く</LhButton>
<LhDialog v-model="dialogVisible2" title="大きなダイアログ" width="600px">
<p>カスタムサイズのダイアログ</p>
<template #footer>
<LhButton @click="dialogVisible2 = false">閉じる</LhButton>
</template>
</LhDialog>
</template>vue
<script>
import { LhButton, LhDialog } from '@lh-ui/vue3'
export default {
components: { LhButton, LhDialog },
data() {
return {
dialogVisible2: false
}
}
}
</script>
<template>
<!-- 幅・高さのカスタマイズ -->
<LhButton @click="dialogVisible2 = true">大きなダイアログを開く</LhButton>
<LhDialog v-model="dialogVisible2" title="大きなダイアログ" width="600px">
<p>カスタムサイズのダイアログ</p>
<template #footer>
<LhButton @click="dialogVisible2 = false">閉じる</LhButton>
</template>
</LhDialog>
</template>ドラッグ可能
ドラッグ可能
vue
<script setup lang="ts">
import { ref } from 'vue'
import { LhButton, LhDialog } from '@lh-ui/vue3'
const dialogVisible3 = ref(false)
</script>
<template>
<!-- ドラッグ可能 -->
<LhButton @click="dialogVisible3 = true">ドラッグ可能なダイアログを開く</LhButton>
<LhDialog v-model="dialogVisible3" title="ドラッグ可能なダイアログ" draggable>
<p>タイトルバーをドラッグするとこのダイアログを移動できます。</p>
<template #footer>
<LhButton @click="dialogVisible3 = false">閉じる</LhButton>
</template>
</LhDialog>
</template>vue
<script>
import { LhButton, LhDialog } from '@lh-ui/vue3'
export default {
components: { LhButton, LhDialog },
data() {
return {
dialogVisible3: false
}
}
}
</script>
<template>
<!-- ドラッグ可能 -->
<LhButton @click="dialogVisible3 = true">ドラッグ可能なダイアログを開く</LhButton>
<LhDialog v-model="dialogVisible3" title="ドラッグ可能なダイアログ" draggable>
<p>タイトルバーをドラッグするとこのダイアログを移動できます。</p>
<template #footer>
<LhButton @click="dialogVisible3 = false">閉じる</LhButton>
</template>
</LhDialog>
</template>カスタムテーマ
ダイアログにカスタムテーマ色を適用します。
青花瓷テーマのダイアログ
vue
<script setup lang="ts">
import { ref } from 'vue'
import { LhConfigProvider, LhButton, LhDialog } from '@lh-ui/vue3'
const dialogThemeVisible = ref(false)
const cerblueTheme = {
'primary-color': '#2B4C7C',
'primary-color-hover': '#3D649E',
'primary-color-bg': '#E8EDF3',
}
</script>
<template>
<LhConfigProvider :theme-vars="cerblueTheme">
<!-- 青花瓷テーマ -->
<LhButton @click="dialogThemeVisible = true" type="primary">テーマダイアログを開く</LhButton>
<LhDialog v-model="dialogThemeVisible" title="青花瓷テーマ">
<p>このダイアログは青花瓷テーマの色を使用します</p>
<template #footer>
<LhButton @click="dialogThemeVisible = false">閉じる</LhButton>
</template>
</LhDialog>
</LhConfigProvider>
</template>vue
<script>
import { LhConfigProvider, LhButton, LhDialog } from '@lh-ui/vue3'
export default {
components: { LhConfigProvider, LhButton, LhDialog },
data() {
return {
dialogThemeVisible: false,
cerblueTheme: {
'primary-color': '#2B4C7C',
'primary-color-hover': '#3D649E',
'primary-color-bg': '#E8EDF3',
},
}
},
}
</script>
<template>
<LhConfigProvider :theme-vars="cerblueTheme">
<!-- 青花瓷テーマ -->
<LhButton @click="dialogThemeVisible = true" type="primary">テーマダイアログを開く</LhButton>
<LhDialog v-model="dialogThemeVisible" title="青花瓷テーマ">
<p>このダイアログは青花瓷テーマの色を使用します</p>
<template #footer>
<LhButton @click="dialogThemeVisible = false">閉じる</LhButton>
</template>
</LhDialog>
</LhConfigProvider>
</template>テーマの詳細は テーマカスタマイズ を参照してください。
sx クイックレイアウト
sx プロパティで Dialog の寸法と間隔を手早く設定できます。
sx クイックレイアウト
vue
<script setup lang="ts">
import { ref } from 'vue'
import { LhButton, LhDialog } from '@lh-ui/vue3'
const visible = ref(false)
</script>
<template>
<!-- ダイアログを開く -->
<LhButton @click="visible = true">ダイアログを開く</LhButton>
<!-- sx レイアウトのダイアログ -->
<LhDialog v-model="visible" title="sx レイアウト" :sx="{ maxWidth: 400 }">
<p>最大幅を設定しました</p>
<template #footer>
<LhButton @click="visible = false">キャンセル</LhButton>
</template>
</LhDialog>
</template>vue
<script>
import { LhButton, LhDialog } from '@lh-ui/vue3'
export default {
components: { LhButton, LhDialog },
data() {
return { visible: false }
},
}
</script>
<template>
<!-- ダイアログを開く -->
<LhButton @click="visible = true">ダイアログを開く</LhButton>
<!-- sx レイアウトのダイアログ -->
<LhDialog v-model="visible" title="sx レイアウト" :sx="{ maxWidth: 400 }">
<p>最大幅を設定しました</p>
<template #footer>
<LhButton @click="visible = false">キャンセル</LhButton>
</template>
</LhDialog>
</template>国際化
ダイアログのテキストは LhConfigProvider と言語パックを組み合わせることで国際化切り替えを実現できます。
国際化
vue
<script setup lang="ts">
import { ref, computed } from 'vue'
import { LhConfigProvider, LhButton, LhDialog, jaJP, enUS } from '@lh-ui/vue3'
const locale = ref('ja-JP')
const i18nVisible = ref(false)
const messages = computed(() => (locale.value === 'zh-CN' ? zhCN : enUS))
</script>
<template>
<LhConfigProvider :locale="messages">
<!-- ダイアログを開く -->
<LhButton @click="i18nVisible = true">
{{ locale === 'zh-CN' ? '打开对话框' : 'Open Dialog' }}
</LhButton>
<!-- 国際化ダイアログ -->
<LhDialog v-model="i18nVisible" :title="locale === 'zh-CN' ? '提示' : 'Notice'">
<p>{{ locale === 'zh-CN' ? '对话框内容' : 'Dialog content' }}</p>
<template #footer>
<LhButton @click="i18nVisible = false">
{{ locale === 'zh-CN' ? '取消' : 'Cancel' }}
</LhButton>
</template>
</LhDialog>
</LhConfigProvider>
</template>vue
<script>
import { LhConfigProvider, LhButton, LhDialog, jaJP, enUS } from '@lh-ui/vue3'
export default {
components: { LhConfigProvider, LhButton, LhDialog },
data() {
return {
locale: 'ja-JP',
i18nVisible: false,
}
},
computed: {
messages() {
return this.locale === 'zh-CN' ? zhCN : enUS
},
},
}
</script>
<template>
<LhConfigProvider :locale="messages">
<!-- ダイアログを開く -->
<LhButton @click="i18nVisible = true">
{{ locale === 'zh-CN' ? '打开对话框' : 'Open Dialog' }}
</LhButton>
<!-- 国際化ダイアログ -->
<LhDialog v-model="i18nVisible" :title="locale === 'zh-CN' ? '提示' : 'Notice'">
<p>{{ locale === 'zh-CN' ? '对话框内容' : 'Dialog content' }}</p>
<template #footer>
<LhButton @click="i18nVisible = false">
{{ locale === 'zh-CN' ? '取消' : 'Cancel' }}
</LhButton>
</template>
</LhDialog>
</LhConfigProvider>
</template>動作スイッチ
閉じ方 / スクロールロック / beforeClose
vue
<script setup lang="ts">
import { ref } from 'vue'
import { LhButton, LhDialog } from '@lh-ui/vue3'
const dialogAdv1 = ref(false)
const dialogAdv2 = ref(false)
const dialogAdv3 = ref(false)
function handleAdvBeforeClose(done: () => void) {
setTimeout(done, 500)
}
</script>
<template>
<!-- ボタンのみで閉じる -->
<LhButton @click="dialogAdv1 = true">ボタンのみで閉じる</LhButton>
<LhDialog
v-model="dialogAdv1"
title="ボタンのみで閉じる"
:show-close="false"
:close-on-click-modal="false"
:close-on-press-escape="false"
>
<p>右上の閉じるボタンを非表示にし、オーバーレイクリックや ESC キーでも閉じなくなります。フッターのボタンからのみ閉じられます。</p>
<template #footer>
<LhButton type="primary" @click="dialogAdv1 = false">了解しました</LhButton>
</template>
</LhDialog>
<!-- スクロールをロックしない -->
<LhButton @click="dialogAdv2 = true">スクロールをロックしない</LhButton>
<LhDialog v-model="dialogAdv2" title="スクロールをロックしない" :lock-scroll="false">
<p>ダイアログを開いている間もページをスクロールできます。内容の短い軽量な通知向きです。</p>
</LhDialog>
<!-- 非同期で閉じる -->
<LhButton @click="dialogAdv3 = true">非同期で閉じる</LhButton>
<LhDialog v-model="dialogAdv3" title="非同期で閉じる" :before-close="handleAdvBeforeClose">
<p>右上の閉じるボタン、オーバーレイ、ESC のいずれかを操作した後、500ms 遅れて実際に閉じられます(クローズ前バリデーションのシミュレーション)。</p>
</LhDialog>
</template>vue
<script>
import { LhButton, LhDialog } from '@lh-ui/vue3'
export default {
components: { LhButton, LhDialog },
data() {
return {
dialogAdv1: false,
dialogAdv2: false,
dialogAdv3: false,
}
},
methods: {
handleAdvBeforeClose(done) {
setTimeout(done, 500)
},
},
}
</script>
<template>
<!-- ボタンのみで閉じる -->
<LhButton @click="dialogAdv1 = true">ボタンのみで閉じる</LhButton>
<LhDialog
v-model="dialogAdv1"
title="ボタンのみで閉じる"
:show-close="false"
:close-on-click-modal="false"
:close-on-press-escape="false"
>
<p>右上の閉じるボタンを非表示にし、オーバーレイクリックや ESC キーでも閉じなくなります。フッターのボタンからのみ閉じられます。</p>
<template #footer>
<LhButton type="primary" @click="dialogAdv1 = false">了解しました</LhButton>
</template>
</LhDialog>
<!-- スクロールをロックしない -->
<LhButton @click="dialogAdv2 = true">スクロールをロックしない</LhButton>
<LhDialog v-model="dialogAdv2" title="スクロールをロックしない" :lock-scroll="false">
<p>ダイアログを開いている間もページをスクロールできます。内容の短い軽量な通知向きです。</p>
</LhDialog>
<!-- 非同期で閉じる -->
<LhButton @click="dialogAdv3 = true">非同期で閉じる</LhButton>
<LhDialog v-model="dialogAdv3" title="非同期で閉じる" :before-close="handleAdvBeforeClose">
<p>右上の閉じるボタン、オーバーレイ、ESC のいずれかを操作した後、500ms 遅れて実際に閉じられます(クローズ前バリデーションのシミュレーション)。</p>
</LhDialog>
</template>位置と重ね順
fullscreen / position / top / zIndex / center
vue
<script setup lang="ts">
import { ref } from 'vue'
import { LhButton, LhDialog } from '@lh-ui/vue3'
const dialogAdv4 = ref(false)
const dialogAdv5 = ref(false)
const dialogAdv6 = ref(false)
const dialogAdv7 = ref(false)
</script>
<template>
<!-- 全画面 -->
<LhButton @click="dialogAdv4 = true">全画面</LhButton>
<LhDialog v-model="dialogAdv4" title="全画面ダイアログ" fullscreen>
<p>fullscreen の場合、ダイアログはビューポート全体を覆います。</p>
</LhDialog>
<!-- 下部位置 -->
<LhButton @click="dialogAdv5 = true">下部位置</LhButton>
<LhDialog v-model="dialogAdv5" title="下部位置" position="bottom">
<p>position が bottom の場合、ダイアログはビューポート下部に寄って表示されます。</p>
</LhDialog>
<!-- 上部オフセット + 重ね順 -->
<LhButton @click="dialogAdv6 = true">上部オフセット + 重ね順</LhButton>
<LhDialog v-model="dialogAdv6" title="上部オフセット + 重ね順" position="top" top="10vh" :z-index="3000">
<p>top はビューポート上部からの距離を調整し、z-index は重ね順を制御します。</p>
</LhDialog>
<!-- 内容の中央揃え -->
<LhButton @click="dialogAdv7 = true">内容を中央揃え(center)</LhButton>
<LhDialog v-model="dialogAdv7" title="内容の中央揃え" center>
<p>center はタイトルと内容を中央揃えで表示します(旧バージョン互換用。新規コードでは position を推奨)。</p>
<template #footer>
<LhButton @click="dialogAdv7 = false">キャンセル</LhButton>
<LhButton type="primary" @click="dialogAdv7 = false">OK</LhButton>
</template>
</LhDialog>
</template>vue
<script>
import { LhButton, LhDialog } from '@lh-ui/vue3'
export default {
components: { LhButton, LhDialog },
data() {
return {
dialogAdv4: false,
dialogAdv5: false,
dialogAdv6: false,
dialogAdv7: false,
}
},
}
</script>
<template>
<!-- 全画面 -->
<LhButton @click="dialogAdv4 = true">全画面</LhButton>
<LhDialog v-model="dialogAdv4" title="全画面ダイアログ" fullscreen>
<p>fullscreen の場合、ダイアログはビューポート全体を覆います。</p>
</LhDialog>
<!-- 下部位置 -->
<LhButton @click="dialogAdv5 = true">下部位置</LhButton>
<LhDialog v-model="dialogAdv5" title="下部位置" position="bottom">
<p>position が bottom の場合、ダイアログはビューポート下部に寄って表示されます。</p>
</LhDialog>
<!-- 上部オフセット + 重ね順 -->
<LhButton @click="dialogAdv6 = true">上部オフセット + 重ね順</LhButton>
<LhDialog v-model="dialogAdv6" title="上部オフセット + 重ね順" position="top" top="10vh" :z-index="3000">
<p>top はビューポート上部からの距離を調整し、z-index は重ね順を制御します。</p>
</LhDialog>
<!-- 内容の中央揃え -->
<LhButton @click="dialogAdv7 = true">内容を中央揃え(center)</LhButton>
<LhDialog v-model="dialogAdv7" title="内容の中央揃え" center>
<p>center はタイトルと内容を中央揃えで表示します(旧バージョン互換用。新規コードでは position を推奨)。</p>
<template #footer>
<LhButton @click="dialogAdv7 = false">キャンセル</LhButton>
<LhButton type="primary" @click="dialogAdv7 = false">OK</LhButton>
</template>
</LhDialog>
</template>Dialog API
Props
| プロパティ | 説明 | 型 | デフォルト値 |
|---|---|---|---|
| modelValue | ダイアログを表示するかどうか | boolean | false |
| title | ダイアログのタイトル | string | '' |
| width | ダイアログの幅 | string | number | '480px' |
| fullscreen | 全画面にするかどうか | boolean | false |
| showClose | 閉じるボタンを表示するかどうか | boolean | true |
| closeOnClickModal | オーバーレイをクリックしたときに閉じるかどうか | boolean | true |
| closeOnPressEscape | ESC キーで閉じるかどうか | boolean | true |
| draggable | ドラッグ可能かどうか | boolean | false |
| center | 中央揃えで表示するかどうか(旧バージョン互換用。position を推奨) | boolean | false |
| position | ダイアログの位置:top / center / bottom | "top" | "center" | "bottom" | 'center' |
| lockScroll | スクロールをロックするかどうか | boolean | true |
| beforeClose | クローズ前のコールバック | (done: () => void) => void | — |
| top | 上部からの距離(px) | string | '15vh' |
| zIndex | z-index | number | — |
| themeVars | コンポーネントレベルのテーマ変数。ConfigProvider の設定を上書きします | { [x: string]: string; } | — |
| bgPattern | コンポーネントレベルの背景紋様。ConfigProvider の設定を上書きします | string | — |
| sx | sx クイックレイアウトプロパティ | LhSxProps | — |
Events
| イベント名 | 説明 | コールバック引数 |
|---|---|---|
| update:modelValue | 表示状態の変化 | (value: boolean) |
| open | 開くアニメーションの終了 | — |
| close | 閉じるアニメーションの終了 | — |
| opened | ダイアログが完全に開いた後にトリガー | — |
| closed | ダイアログが完全に閉じた後にトリガー | — |
Slots
| スロット名 | 説明 |
|---|---|
| default | ダイアログの内容 |
| header | ダイアログのタイトル領域 |
| footer | ダイアログのフッター領域 |
型定義
このコンポーネントが外部にエクスポートする TypeScript の型構造を以下に示します(packages/components/dialog/src/types.ts および @lh-ui/share/core/* のソースから自動抽出。各エントリーをクリックすると完全な定義が表示されます。プロパティの説明は上の Props 表を参照してください):
LhDialogProps
ts
/**
* Dialog コンポーネントの Props
*/
export interface LhDialogProps {
/** 表示するかどうか */
modelValue?: boolean
/** タイトル */
title?: string
/** 幅 */
width?: string | number
/** 全画面にするかどうか */
fullscreen?: boolean
/** 閉じるボタンを表示するかどうか */
showClose?: boolean
/** オーバーレイクリックで閉じるかどうか */
closeOnClickModal?: boolean
/** ESC キーで閉じるかどうか */
closeOnPressEscape?: boolean
/** ドラッグ可能かどうか */
draggable?: boolean
/** 中央揃えで表示するかどうか(旧バージョン互換用。position を推奨) */
center?: boolean
/** ダイアログの位置:top / center / bottom */
position?: 'top' | 'center' | 'bottom'
/** スクロールをロックするかどうか */
lockScroll?: boolean
/** クローズ前のコールバック */
beforeClose?: (done: () => void) => void
/** 上部からの距離(px) */
top?: string
/** z-index */
zIndex?: number
/** コンポーネントレベルのテーマ変数。ConfigProvider の設定を上書き */
themeVars?: Record<string, string>
/** コンポーネントレベルの背景紋様。ConfigProvider の設定を上書き */
bgPattern?: string
/** sx クイックレイアウトプロパティ */
sx?: LhSxProps
}