Dialog ダイアログ - Vant 4
Dialog ダイアログ
🎯 紹介
ダイアログはユーザーインタラクションにおける重要な役割です!丁寧なウェイターのように、重要な瞬間に現れて、ユーザーに重要な情報を伝えたり確認を求めたりします。優しいお知らせ、重要な確認、複雑な操作など、Dialog はいつも優雅に任務をこなします。コンポーネント呼び出しと関数呼び出しの2つの方法をサポートしており、開発をより柔軟に行うことができます。
📦 導入
以下の方法でグローバルにコンポーネントを登録します。詳細な登録方法についてはコンポーネントの登録を参照してください。
import { createApp } from 'vue';
import { Dialog } from 'vant';
const app = createApp();
app.use(Dialog);🚀 関数呼び出し
開発の効率化のため、Vant は非常に便利な一連のヘルパー関数を提供しています!これらの関数を使用すると、魔法のように簡単にグローバルなダイアログコンポーネントを呼び出すことができます。
たとえば showDialog 関数を使用すれば、一行のコードでページに美しいダイアログを表示することができます。
import { showDialog } from 'vant';
showDialog({
message: 'これは友好的なヒントです!'
});🎨 コードデモ
💬 メッセージ表示 - 優しい情報の伝達者
最もシンプルかつ親切な使い方です!ユーザーに重要な情報を伝える必要があるとき、メッセージ表示は優しい使者のように、優雅にユーザーの前に現れます。デフォルトでは確認ボタンのみを含み、シンプルかつ明確で、ユーザーが情報そのものに集中できます。
import { showDialog } from 'vant';
showDialog({
title: '優しいお知らせ',
message: 'コードは人間が読むために書かれており、機械が実行できることは副次的な効果です。',
}).then(() => {
// ユーザーが確認をクリックした後のコールバック
console.log('ユーザーが確認しました');
});
showDialog({
message: '人生はただ忙しく回ることだけではなく、人間の体験はもっと広く、豊かなものです。',
}).then(() => {
// ユーザーがダイアログを閉じた後のコールバック
console.log('ダイアログが閉じられました');
});❓ メッセージ確認 - 賢明な決定アシスタント
ユーザーに重要な決定を下させる必要があるとき、メッセージ確認は賢明な顧問のように、ユーザーに明確な選択を提供します。デフォルトで確認とキャンセルのボタンを含み、ユーザーが熟考した後に最適な選択を下すことができます。
import { showConfirmDialog } from'vant'; showConfirmDialog({ title: 'タイトル', message: '解決策が醜いなら、きっとより良い解決策があるはずです。まだ発見されていないだけです。', }) .then(() => { // on confirm }) .catch(() => { // on cancel });🎨 角丸ボタンスタイル - 柔らかい視覚体験
ダイアログをより柔らかく可愛くしましょう!theme オプションを round-button に設定すると、角丸ボタンスタイルのダイアログが表示され、丸みを帯びたエッジが春風のように穏やかで、ユーザーにより快適な視覚体験をもたらします。
import { showDialog } from'vant'; showDialog({ title: 'タイトル', message: 'コードは人間が読むために書かれており、機械が実行できることは副次的な効果です。', theme: 'round-button', }).then(() => { // on close }); showDialog({ message: '人生はただ忙しく回ることだけではなく、人間の体験はもっと広く、豊かなものです。', theme: 'round-button', }).then(() => { // on close });⏳ 非同期での閉じる - 優雅な別れの儀式
別れも優雅なプロセスが必要なことがあります!beforeClose 属性という丁寧な執事を通じて、コールバック関数を渡すことができ、ダイアログが閉じる前に特定の操作を実行し、閉じるたびに落ち着いた雰囲気を作ることができます。
import { showConfirmDialog } from'vant'; constbeforeClose = (action) => newPromise((resolve) => { setTimeout(() => { // action !== 'confirm' キャンセル操作をブロックresolve(action === 'confirm'); }, 1000); }); showConfirmDialog({ title: 'タイトル', message: '解決策が醜いなら、きっとより良い解決策があるはずです。まだ発見されていないだけです。', beforeClose, });🧩 Dialog コンポーネントの使用 - 自由創作のキャンバス
より多くの創造の自由が必要な場合、Dialog コンポーネントはあなたの創意を待つ白紙のキャンバスのようです!Dialog 内にコンポーネントやその他のカスタムコンテンツを埋め込む必要がある場合は、Dialog コンポーネントを直接使用し、デフォルトスロットを使用してカスタマイズすることができます。使用する前に app.use などの方法でコンポーネントを登録する必要があります。
import { ref } from'vue'; exportdefault { setup() { const show = ref(false); return { show }; }, };API
メソッド
Vant では以下の Dialog 関連のヘルパー関数がエクスポートされています:
| メソッド名 | 説明 | パラメータ | 戻り値 |
|---|---|---|---|
| showDialog | メッセージ表示ダイアログを表示します、デフォルトで確認ボタンを含みます | options: DialogOptions | Promise<void> |
| showConfirmDialog | メッセージ確認ダイアログを表示します、デフォルトで確認とキャンセルボタンを含みます | options: DialogOptions | Promise<void> |
| closeDialog | 現在表示されているダイアログを閉じます | - | void |
| setDialogDefaultOptions | デフォルト設定を変更し、すべての showDialog 呼び出しに影響します | options: DialogOptions | void |
| resetDialogDefaultOptions | デフォルト設定をリセットし、すべての showDialog 呼び出しに影響します | - | void |
DialogOptions
showDialog などのメソッドを呼び出す際、以下のオプションを渡すことができます:
| パラメータ | 説明 | タイプ | デフォルト値 |
|---|---|---|---|
| title | タイトル | string | - |
| width | ダイアログの幅、デフォルトの単位は px | number | string | 320px |
| message | テキストコンテンツ、\n での改行をサポート | string | () => JSX.ELement | - |
| messageAlign | 内容の揃え方、left``right が使用可能 | string | center |
| theme | スタイル、round-button が使用可能 | string | default |
| className | カスタムクラス名 | string | Array | object | - |
| showConfirmButton | 確認ボタンを表示するかどうか | boolean | true |
| showCancelButton | キャンセルボタンを表示するかどうか | boolean | false |
| confirmButtonText | 確認ボタンのテキスト | string | 確認 |
| confirmButtonColor | 確認ボタンの色 | string | #ee0a24 |
| confirmButtonDisabled | 確認ボタンを無効にするかどうか | boolean | false | | cancelButtonText | キャンセルボタンのテキスト | string | キャンセル | | cancelButtonColor | キャンセルボタンの色 | string | black | | cancelButtonDisabled | キャンセルボタンを無効にするかどうか | boolean | false | | destroyOnClose v4.9.18 | 閉じるときにコンテンツを破棄するかどうか | boolean | false | | overlay | オーバーレイを表示するかどうか | boolean | true | | overlayClass | カスタムオーバーレイクラス名 | string | Array | object | - | | overlayStyle | カスタムオーバーレイスタイル | object | - | | closeOnPopstate | ページの戻る操作時に自動的に閉じるかどうか | boolean | true | | closeOnClickOverlay | オーバーレイをクリックした後にダイアログを閉じるかどうか | boolean | false | | lockScroll | 背景のスクロールをロックするかどうか | boolean | true | | allowHtml | message コンテンツで HTML をレンダリングするかどうかを許可するかどうか | boolean | false | | beforeClose | 閉じる前のコールバック関数、false を返すと閉じるのを防ぐことができ、Promise の返却もサポート | (action: string) => boolean | Promise<boolean> | - | | transition | アニメーションクラス名、transition の name 属性と同等 | string | - |
| teleport | マウント先のノードを指定します、Teleport コンポーネントの to 属性 と同等 | string | Element | body |
| keyboardEnabled | キーボード機能を有効にするかどうか、確認とキャンセルボタンを表示する場合、デフォルトではキーボードの Enter と Esc が confirm と cancel 関数を実行します | boolean | true |
Props
コンポーネントから Dialog を呼び出す際、以下の Props がサポートされています:
| パラメータ | 説明 | タイプ | デフォルト値 |
|---|---|---|---|
| v-model:show | ダイアログを表示するかどうか | boolean | - |
| title | タイトル | string | - |
| width | ダイアログの幅、デフォルトの単位は px | number | string | 320px |
| message | テキストコンテンツ、\n での改行をサポート | string | () => JSX.Element | - |
| message-align | 内容の水平揃え、left``right``justify が使用可能 | string | center |
| theme | スタイル、round-button が使用可能 | string | default |
| show-confirm-button | 確認ボタンを表示するかどうか | boolean | true |
| show-cancel-button | キャンセルボタンを表示するかどうか | boolean | false |
| confirm-button-text | 確認ボタンのテキスト | string | 確認 |
| confirm-button-color | 確認ボタンの色 | string | #ee0a24 |
| confirm-button-disabled | 確認ボタンを無効にするかどうか | boolean | false | | cancel-button-text | キャンセルボタンのテキスト | string | キャンセル | | cancel-button-color | キャンセルボタンの色 | string | black | | cancel-button-disabled | キャンセルボタンを無効にするかどうか | boolean | false | | destroy-on-close v4.9.18 | 閉じるときにコンテンツを破棄するかどうか | boolean | false | | z-index | ダイアログの z-index レベルを固定値に設定します | number | string | 2000+ | | overlay | オーバーレイを表示するかどうか | boolean | true | | overlay-class | カスタムオーバーレイクラス名 | string | - | | overlay-style | カスタムオーバーレイスタイル | object | - | | close-on-popstate | ページの戻る操作時に自動的に閉じるかどうか | boolean | true | | close-on-click-overlay | オーバーレイをクリックした後にダイアログを閉じるかどうか | boolean | false | | lazy-render | ポップアップレイヤーを表示するときのみノードをレンダリングするかどうか | boolean | true | | lock-scroll | 背景のスクロールをロックするかどうか | boolean | true | | allow-html | message コンテンツで HTML をレンダリングするかどうかを許可するかどうか | boolean | false | | before-close | 閉じる前のコールバック関数、false を返すと閉じるのを防ぐことができ、Promise の返却もサポート | (action: string) => boolean | Promise<boolean> | - | | transition | アニメーションクラス名、transition の name 属性と同等 | string | - |
| teleport | マウント先のノードを指定します、Teleport コンポーネントの to 属性 と同等 | string | Element | - |
| keyboard-enabled | キーボード機能を有効にするかどうか、確認とキャンセルボタンを表示する場合、デフォルトではキーボードの Enter と Esc が confirm と cancel 関数を実行します | boolean | true |
Events
コンポーネントから Dialog を呼び出す際、以下のイベントがサポートされています:
| イベント名 | 説明 | コールバック引数 |
|---|---|---|
| confirm | 確認ボタンをクリックしたときにトリガーされます | - |
| cancel | キャンセルボタンをクリックしたときにトリガーされます | - |
| open | ダイアログを開いたときにトリガーされます | - |
| close | ダイアログを閉じたときにトリガーされます | - |
| opened | ダイアログを開いてアニメーションが終了した後にトリガーされます | - |
| closed | ダイアログを閉じてアニメーションが終了した後にトリガーされます | - |
Slots
コンポーネントから Dialog を呼び出す際、以下のスロットがサポートされています:
| 名前 | 説明 |
|---|---|
| default | カスタムコンテンツ |
| title | カスタムタイトル |
| footer | カスタムフッターボタン領域 |
型定義
コンポーネントは以下の型定義をエクスポートしています:
importtype { DialogProps, DialogTheme, DialogMessage, DialogOptions, DialogMessageAlign, } from'vant';テーマカスタマイズ
スタイル変数
コンポーネントはカスタムスタイルに使用できる以下の CSS 変数を提供しています。使用方法については ConfigProvider コンポーネント を参照してください。
| 名称 | デフォルト値 | 説明 |
|---|---|---|
| --van-dialog-width | 320px | - |
| --van-dialog-small-screen-width | 90% | - |
| --van-dialog-font-size | var(--van-font-size-lg) | - |
| --van-dialog-transition | var(--van-duration-base) | - |
| --van-dialog-radius | 16px | - |
| --van-dialog-background | var(--van-background-2) | - |
| --van-dialog-header-font-weight | var(--van-font-bold) | - |
| --van-dialog-header-line-height | 24px | - |
| --van-dialog-header-padding-top | 26px | - |
| --van-dialog-header-isolated-padding | var(--van-padding-lg) 0 | - |
| --van-dialog-message-padding | var(--van-padding-lg) | - |
| --van-dialog-message-font-size | var(--van-font-size-md) | - |
| --van-dialog-message-line-height | var(--van-line-height-md) | - |
| --van-dialog-message-max-height | 60vh | - |
| --van-dialog-has-title-message-text-color | var(--van-gray-7) | - |
| --van-dialog-has-title-message-padding-top | var(--van-padding-xs) | - |
| --van-dialog-button-height | 48px | - |
| --van-dialog-round-button-height | 36px | - |
| --van-dialog-confirm-button-text-color | var(--van-primary-color) | - |
よくある質問
showDialog を参照するとコンパイルエラーが発生する?
showDialog メソッドを参照すると以下のようなエラーが発生する場合、プロジェクトで babel-plugin-import プラグインが使用されているため、コードが誤ってコンパイルされています。
These dependencies were not found: * vant/es/show-dialog in ./src/xxx.js * vant/es/show-dialog/style in ./src/xxx.jsVant はバージョン 4.0 から babel-plugin-import プラグインをサポートしなくなりました。移行ガイド を参照して、このプラグインを削除してください。
beforeRouteLeave で Dialog を呼び出しても表示されない?
closeOnPopstate 属性を false に設定すれば解決します。
import { showDialog } from'vant'; showDialog({ title: 'タイトル', message: 'ダイアログの内容', closeOnPopstate: false, }).then(() => { // on close });🎯 ベストプラクティス
スマートなダイアログ管理システム
// スマートなダイアログマネージャーを作成
class DialogManager {
constructor() {
this.queue = [];
this.isShowing = false;
}
// ダイアログをキューに追加
add(options) {
return new Promise((resolve, reject) => {
this.queue.push({
options,
resolve,
reject
});
this.processQueue();
});
}
// ダイアログキューを処理
async processQueue() {
if (this.isShowing || this.queue.length === 0) return;
this.isShowing = true;
const { options, resolve, reject } = this.queue.shift();
try {
await showDialog(options);
resolve();
} catch (error) {
reject(error);
} finally {
this.isShowing = false;
// 次のダイアログを処理
setTimeout(() => this.processQueue(), 100);
}
}
}
// 使用例
const dialogManager = new DialogManager();
// ダイアログをバッチ表示、自動的にキューイング
dialogManager.add({ message: '最初のダイアログ' });
dialogManager.add({ message: '2番目のダイアログ' });
dialogManager.add({ message: '3番目のダイアログ' });レスポンシブダイアログデザイン
// デバイスタイプに応じてダイアログスタイルを調整
const createResponsiveDialog = (options) => {
const isMobile = window.innerWidth <= 768;
const isTablet = window.innerWidth > 768 && window.innerWidth <= 1024;
const responsiveOptions = {
...options,
width: isMobile ? '90%' : isTablet ? '400px' : '480px',
className: `dialog-${isMobile ? 'mobile' : isTablet ? 'tablet' : 'desktop'}`
};
return showDialog(responsiveOptions);
};
// 使用例
createResponsiveDialog({
title: 'レスポンシブダイアログ',
message: 'このダイアログはデバイスサイズに応じて自動的にスタイルを調整します'
});テーマ化されたダイアログ設定
// プリセットテーマ設定
const dialogThemes = {
success: {
confirmButtonColor: '#07c160',
title: '✅ 成功',
theme: 'round-button'
},
warning: {
confirmButtonColor: '#ff976a',
title: '⚠️ 警告',
theme: 'round-button'
},
error: {
confirmButtonColor: '#ee0a24',
title: '❌ エラー',
theme: 'round-button'
},
info: {
confirmButtonColor: '#1989fa',
title: 'ℹ️ ヒント',
theme: 'round-button'
}
};
// ショートカットメソッド
const showSuccessDialog = (message) => showDialog({
...dialogThemes.success,
message
});
const showErrorDialog = (message) => showDialog({
...dialogThemes.error,
message
});💡 使用テクニック
動的コンテンツダイアログ
// 動的にコンテンツを更新できるダイアログ
const showDynamicDialog = (initialMessage) => {
let dialogInstance;
const updateMessage = (newMessage) => {
if (dialogInstance) {
// 再呼び出してコンテンツを更新
closeDialog();
setTimeout(() => {
dialogInstance = showDialog({
message: newMessage,
showCancelButton: true
});
}, 100);
}
};
dialogInstance = showDialog({
message: initialMessage,
showCancelButton: true,
beforeClose: (action) => {
if (action === 'confirm') {
updateMessage('コンテンツが更新されました!');
return false; // 閉じるのを防ぐ
}
return true;
}
});
return { updateMessage };
};フォーム検証ダイアログ
// フォーム検証結果ダイアログ
const showValidationDialog = (errors) => {
const errorList = errors.map(error => `• ${error}`).join('\n');
return showDialog({
title: 'フォーム検証に失敗しました',
message: `以下のエラーを修正してください:\n\n${errorList}`,
confirmButtonText: 'わかりました',
confirmButtonColor: '#ff976a',
allowHtml: false
});
};
// 使用例
const validateForm = (formData) => {
const errors = [];
if (!formData.name) errors.push('名前は必須です');
if (!formData.email) errors.push('メールアドレスは必須です');
if (formData.age < 18) errors.push('年齢は18歳以上でなければなりません');
if (errors.length > 0) {
showValidationDialog(errors);
return false;
}
return true;
};カウントダウン確認ダイアログ
// カウントダウン付きの確認ダイアログ
const showCountdownDialog = (message, countdown = 5) => {
let timer;
let currentCount = countdown;
const updateDialog = () => {
const buttonText = currentCount > 0 ? `確認 (${currentCount}s)` : '確認';
return showDialog({
message,
confirmButtonText: buttonText,
confirmButtonDisabled: currentCount > 0,
showCancelButton: true,
beforeClose: (action) => {
if (timer) clearInterval(timer);
return true;
}
});
};
// カウントダウンを開始
timer = setInterval(() => {
currentCount--;
if (currentCount >= 0) {
closeDialog();
setTimeout(() => updateDialog(), 50);
} else {
clearInterval(timer);
}
}, 1000);
return updateDialog();
};🔧 よくある問題と解決策
ダイアログレイヤー管理
// ダイアログレイヤーマネージャー
class DialogZIndexManager {
constructor() {
this.baseZIndex = 2000;
this.currentZIndex = this.baseZIndex;
}
getNextZIndex() {
return ++this.currentZIndex;
}
resetZIndex() {
this.currentZIndex = this.baseZIndex;
}
}
const zIndexManager = new DialogZIndexManager();
// 使用例
const showLayeredDialog = (options) => {
return showDialog({
...options,
overlayStyle: {
zIndex: zIndexManager.getNextZIndex()
}
});
};メモリリークの防止
// メモリリークを防止するダイアログラッパー
const createSafeDialog = (options) => {
const cleanup = () => {
// イベントリスナーをクリーンアップ
window.removeEventListener('beforeunload', cleanup);
// タイマーをクリーンアップ
if (options._timer) {
clearTimeout(options._timer);
}
};
// ページがアンロードされるときに自動的にクリーンアップ
window.addEventListener('beforeunload', cleanup);
return showDialog({
...options,
beforeClose: (action) => {
cleanup();
return options.beforeClose ? options.beforeClose(action) : true;
}
});
};アクセシビリティの最適化
// アクセシビリティの強化
const showAccessibleDialog = (options) => {
return showDialog({
...options,
// ARIA 属性を追加
className: 'dialog-accessible',
beforeClose: (action) => {
// フォーカスをトリガー要素に戻す
const triggerElement = document.activeElement;
if (triggerElement && triggerElement.focus) {
setTimeout(() => triggerElement.focus(), 100);
}
return options.beforeClose ? options.beforeClose(action) : true;
}
});
};
// 対応する CSS
const accessibleDialogStyles = `
.dialog-accessible {
outline: none;
}
.dialog-accessible [role="dialog"] {
outline: 2px solid #1989fa;
outline-offset: 2px;
}
@media (prefers-reduced-motion: reduce) {
.dialog-accessible * {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
`;🎨 デザインのインスピレーション
フロストグラス効果ダイアログ
/* フロストグラス効果 */
.dialog-glass {
backdrop-filter: blur(10px);
background: rgba(255, 255, 255, 0.8);
border: 1px solid rgba(255, 255, 255, 0.2);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
}
.dialog-glass .van-overlay {
background: rgba(0, 0, 0, 0.2);
backdrop-filter: blur(5px);
}アニメーション効果の強化
/* 弾力アニメーション */
@keyframes dialogBounceIn {
0% {
opacity: 0;
transform: scale(0.3) translate(-50%, -50%);
}
50% {
opacity: 1;
transform: scale(1.05) translate(-50%, -50%);
}
70% {
transform: scale(0.9) translate(-50%, -50%);
}
100% {
opacity: 1;
transform: scale(1) translate(-50%, -50%);
}
}
.dialog-bounce .van-dialog {
animation: dialogBounceIn 0.6s cubic-bezier(0.68, -0.55, 0.265, 1.55);
}
/* グラデーションボーダー */
.dialog-gradient-border {
position: relative;
background: linear-gradient(45deg, #ff6b6b, #4ecdc4, #45b7d1, #96ceb4);
background-size: 400% 400%;
animation: gradientShift 3s ease infinite;
padding: 2px;
border-radius: 18px;
}
.dialog-gradient-border .van-dialog {
background: white;
border-radius: 16px;
}
@keyframes gradientShift {
0% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
100% { background-position: 0% 50%; }
}テーマ切り替えアニメーション
// テーマ切り替えアニメーション
const switchDialogTheme = (fromTheme, toTheme) => {
const dialog = document.querySelector('.van-dialog');
if (!dialog) return;
// 遷移効果を追加
dialog.style.transition = 'all 0.3s ease';
// 古いテーマクラスを削除
dialog.classList.remove(`dialog-theme-${fromTheme}`);
// 新しいテーマクラスを追加
setTimeout(() => {
dialog.classList.add(`dialog-theme-${toTheme}`);
}, 50);
};🚀 高度な機能拡張
スマートダイアログ推奨システム
// ユーザー行動に基づくダイアログ推奨
class DialogRecommendationEngine {
constructor() {
this.userBehavior = JSON.parse(localStorage.getItem('dialogBehavior') || '{}');
}
// ユーザー行動を記録
recordBehavior(dialogType, action, duration) {
if (!this.userBehavior[dialogType]) {
this.userBehavior[dialogType] = {
confirmCount: 0,
cancelCount: 0,
avgDuration: 0,
totalShown: 0
};
}
const behavior = this.userBehavior[dialogType];
behavior.totalShown++;
if (action === 'confirm') behavior.confirmCount++;
if (action === 'cancel') behavior.cancelCount++;
// 平均継続時間を更新
behavior.avgDuration = (behavior.avgDuration + duration) / 2;
localStorage.setItem('dialogBehavior', JSON.stringify(this.userBehavior));
}
// 推奨設定を取得
getRecommendedConfig(dialogType) {
const behavior = this.userBehavior[dialogType];
if (!behavior) return {};
const confirmRate = behavior.confirmCount / behavior.totalShown;
return {
// 確認率が低い場合、警告色を追加
confirmButtonColor: confirmRate < 0.3 ? '#ff976a' : '#07c160',
// ユーザーがキャンセルすることが多い場合、デフォルトでキャンセルボタンを表示
showCancelButton: behavior.cancelCount > behavior.confirmCount,
// 平均表示時間に基づいて自動閉鎖を調整
autoClose: behavior.avgDuration < 2000
};
}
}多言語ダイアログシステム
// 多言語ダイアログサポート
class I18nDialogManager {
constructor() {
this.locale = 'zh-CN';
this.messages = {
'zh-CN': {
confirm: '確認',
cancel: 'キャンセル',
ok: 'はい',
warning: '警告',
error: 'エラー',
success: '成功'
},
'en-US': {
confirm: 'Confirm',
cancel: 'Cancel',
ok: 'OK',
warning: 'Warning',
error: 'Error',
success: 'Success'
},
'ja-JP': {
confirm: '確認',
cancel: 'キャンセル',
ok: 'はい',
warning: '警告',
error: 'エラー',
success: '成功'
}
};
}
setLocale(locale) {
this.locale = locale;
}
t(key) {
return this.messages[this.locale][key] || key;
}
showDialog(options) {
return showDialog({
...options,
confirmButtonText: options.confirmButtonText || this.t('confirm'),
cancelButtonText: options.cancelButtonText || this.t('cancel')
});
}
}
// 使用例
const i18nDialog = new I18nDialogManager();
i18nDialog.setLocale('en-US');
i18nDialog.showDialog({
title: 'Confirmation',
message: 'Are you sure you want to delete this item?',
showCancelButton: true
});ダイアログ分析統計
// ダイアログ使用統計分析
class DialogAnalytics {
constructor() {
this.events = [];
}
track(eventType, data) {
this.events.push({
type: eventType,
data,
timestamp: Date.now()
});
// 分析サービスに送信
this.sendToAnalytics(eventType, data);
}
sendToAnalytics(eventType, data) {
// 分析サービスへの送信をシミュレート
console.log('Analytics:', { eventType, data });
}
wrapDialog(options) {
const startTime = Date.now();
this.track('dialog_show', {
type: options.type || 'default',
hasTitle: !!options.title,
hasCancel: !!options.showCancelButton
});
return showDialog({
...options,
beforeClose: (action) => {
const duration = Date.now() - startTime;
this.track('dialog_close', {
action,
duration,
type: options.type || 'default'
});
return options.beforeClose ? options.beforeClose(action) : true;
}
});
}
getStatistics() {
const stats = {
totalShown: 0,
avgDuration: 0,
confirmRate: 0,
cancelRate: 0
};
const showEvents = this.events.filter(e => e.type === 'dialog_show');
const closeEvents = this.events.filter(e => e.type === 'dialog_close');
stats.totalShown = showEvents.length;
if (closeEvents.length > 0) {
stats.avgDuration = closeEvents.reduce((sum, e) => sum + e.data.duration, 0) / closeEvents.length;
stats.confirmRate = closeEvents.filter(e => e.data.action === 'confirm').length / closeEvents.length;
stats.cancelRate = closeEvents.filter(e => e.data.action === 'cancel').length / closeEvents.length;
}
return stats;
}
}📚 関連リンク
技術ドキュメント
- Popup ポップアップレイヤー - ダイアログの基盤実装
- Overlay オーバーレイ - オーバーレイの動作原理を理解する
- Toast トースト - 軽量なメッセージ通知ソリューション
デザインガイド
ユーザーエクスペリエンス
関連コンポーネント
- ActionSheet アクションシート - 下部にポップアップする選択パネル
- Notify 通知 - 上部のメッセージ通知
- ImagePreview 画像プレビュー - 画像プレビューダイアログ
- Picker ピッカー - ピッカーダイアログ