Quasar 对话框非常适合让用户选择某个操作或一系列操作,也可以用来向用户展示重要信息,或要求用户做出决定。
从 UI 角度来看,对话框可以理解为一种浮动的模态窗口,只覆盖屏幕的一部分。因此对话框应该只用于快速的用户交互操作。
TIP
对话框也可以作为 Vue 文件模板中的组件使用(适用于复杂场景,如特定的表单组件、可选选项等)。详情请参阅 QDialog 页面。
使用 Quasar 插件形式的对话框相比 QDialog 组件的优势在于:插件可以在 Vue 环境之外调用,且不需要您管理模板。但相应地,其自定义能力不如组件形式灵活。
不过,您也可以提供一个自定义组件让 Dialog 插件来渲染(参见下方的"调用自定义组件"章节),这是一种很好的方式来避免在 Vue 模板中内联对话框(同时也有助于更好地组织项目文件和复用对话框)。
通过 QDialog 插件,您可以编程式地创建以下三种类型的对话框:
- 提示输入对话框——要求用户在输入框中填写某些数据。
- 选项选择对话框——让用户通过单选按钮或开关(单选)或复选框(多选)来选择选项。
- 简单确认对话框——用户可以取消或确认某个操作。
要创建第 1 种提示输入表单,需要在 opts 对象中使用 prompt 属性。
要创建第 2 种选项选择表单,需要在 opts 对象中使用 options 属性。
// quasar.config file
return {
framework: {
plugins: [
'Dialog'
]
}
}内置组件
import { Dialog } from 'quasar'
(Object) Dialog.create({ ... })
// 在 Vue 文件内部
import { useQuasar } from 'quasar'
setup () {
const $q = useQuasar()
$q.dialog({ ... }) // 返回 Object
}请查看 API 卡片了解返回的 Object 的具体内容。
用法
TIP
查看以下所有示例时,建议同时打开浏览器控制台观察输出。
WARNING
这并不是 Dialog 插件全部功能的完整列表。更多功能请查阅 API 章节。
原生属性
您还可以为内部的 QInput 或 QOptionGroup 组件传递原生 HTML 属性,如下例所示。
用户输入验证
系统提供了基础的验证机制,在用户填写的值不符合预期之前,将无法提交对话框(点击/触摸"确定"或按 ENTER)。
进度展示
使用 HTML
如果指定了 html: true 属性,您可以在标题和消息中使用 HTML。请注意这可能导致 XSS 攻击,请务必自行对消息内容进行安全过滤。
调用自定义组件
您也可以调用自己的自定义组件,而不仅限于使用 Dialog 插件自带的默认组件。但此时您需要自行处理所有逻辑(包括自定义组件的 props)。
这个功能实际上是 Dialog 插件的精华所在。它可以帮助您保持其他 Vue 组件模板的整洁,轻松地将对话框功能分离和复用。
触发自定义组件
/**
* 这种方式也可以在 Vue 组件外部使用
*/
import { Dialog } from 'quasar'
import CustomComponent from '..path.to.component..'
Dialog.create({
component: CustomComponent,
// 转发给自定义组件的 props
componentProps: {
text: 'something',
persistent: true,
// ...更多 props...
}
}).onOk(() => {
console.log('OK')
}).onCancel(() => {
console.log('Cancel')
}).onDismiss(() => {
console.log('Called on OK or Cancel')
})使用选项式 API 的等价写法是直接使用 this.$q.dialog({ ... })。
WARNING
您的自定义组件必须遵循下面描述的接口规范,才能完美接入 Dialog 插件。请注意代码中的 “REQUIRED”(必需)注释,以下仅为最基础的示例骨架。
编写自定义组件
使用 “script setup” 的 SFC 组合式 API 写法
我们将使用 useDialogPluginComponent 组合式函数。
<template>
<q-dialog ref="dialogRef" @hide="onDialogHide">
<q-card class="q-dialog-plugin">
<!--
...内容
... 可以使用 q-card-section 来组织内容
-->
<!-- 按钮示例 -->
<q-card-actions align="right">
<q-btn color="primary" label="OK" @click="onOKClick" />
<q-btn color="primary" label="Cancel" @click="onDialogCancel" />
</q-card-actions>
</q-card>
</q-dialog>
</template>
<script setup>
import { useDialogPluginComponent } from "quasar";
const props = defineProps({
// ...您的自定义 props
});
defineEmits([
// 必需;需要指定组件通过 useDialogPluginComponent() 发出的事件
...useDialogPluginComponent.emits,
]);
const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } = useDialogPluginComponent();
// dialogRef - 应用到 QDialog 的 Vue ref
// onDialogHide - 用作 QDialog @hide 事件的处理函数
// onDialogOK - 以"确认"结果关闭对话框的函数
// 示例:onDialogOK() - 无数据负载
// 示例:onDialogOK({ /*...*/ }) - 带数据负载
// onDialogCancel - 以"取消"结果关闭对话框的函数
// 以下是示例代码(非必需)
function onOKClick() {
// 点击确认时,必须调用 onDialogOK(可选传入数据负载)
onDialogOK();
// 或带数据负载:onDialogOK({ ... })
// ...同时会自动隐藏对话框
}
</script>如果您想使用对象形式定义 emits,则(需要 Quasar v2.2.5+):
defineEmits({
// 必需;需要指定组件通过 useDialogPluginComponent() 发出的事件
...useDialogPluginComponent.emitsObject,
// ...您自己的定义
})使用 “script” 的 SFC 组合式 API 写法
我们将使用 useDialogPluginComponent 组合式函数。
<template>
<!-- 注意这里的 dialogRef -->
<q-dialog ref="dialogRef" @hide="onDialogHide">
<q-card class="q-dialog-plugin">
<!--
...内容
... 可以使用 q-card-section 来组织内容
-->
<!-- 按钮示例 -->
<q-card-actions align="right">
<q-btn color="primary" label="OK" @click="onOKClick" />
<q-btn color="primary" label="Cancel" @click="onCancelClick" />
</q-card-actions>
</q-card>
</q-dialog>
</template>
<script>
import { useDialogPluginComponent } from "quasar";
export default {
props: {
// ...您的自定义 props
},
emits: [
// 必需;需要指定组件通过 useDialogPluginComponent() 发出的事件
...useDialogPluginComponent.emits,
],
setup() {
// 必需;必须在 setup() 中调用
const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } = useDialogPluginComponent();
// dialogRef - 应用到 QDialog 的 Vue ref
// onDialogHide - 用作 QDialog @hide 事件的处理函数
// onDialogOK - 以"确认"结果关闭对话框的函数
// 示例:onDialogOK() - 无数据负载
// 示例:onDialogOK({ /*.../* }) - 带数据负载
// onDialogCancel - 以"取消"结果关闭对话框的函数
return {
// 以下是必需的;
// 需要将 useDialogPluginComponent() 返回的内容
// 注入到 vue 作用域中以供模板使用
dialogRef,
onDialogHide,
// 模板中使用的其他方法;
// 以下是示例代码(非必需)
onOKClick() {
// 点击确认时,必须调用 onDialogOK(可选传入数据负载)
onDialogOK();
// 或带数据负载:onDialogOK({ ... })
// ...同时会自动隐藏对话框
},
// 直接透传 onDialogCancel
onCancelClick: onDialogCancel,
};
},
};
</script>如果您想使用对象形式定义 emits,则(需要 Quasar v2.2.5+):
emits: {
// 必需;需要指定组件通过 useDialogPluginComponent() 发出的事件
...useDialogPluginComponent.emitsObject,
// ...您自己的定义
}使用 “script” 的 SFC 选项式 API 写法
<template>
<q-dialog ref="dialog" @hide="onDialogHide">
<q-card class="q-dialog-plugin">
<!--
...内容
... 可以使用 q-card-section 来组织内容
-->
<!-- 按钮示例 -->
<q-card-actions align="right">
<q-btn color="primary" label="OK" @click="onOKClick" />
<q-btn color="primary" label="Cancel" @click="onCancelClick" />
</q-card-actions>
</q-card>
</q-dialog>
</template>
<script>
export default {
props: {
// ...您的自定义 props
},
emits: [
// 必需
"ok",
"hide",
],
methods: {
// 以下方法是必需的
// (不要更改方法名 --> "show")
show() {
this.$refs.dialog.show();
},
// 以下方法是必需的
// (不要更改方法名 --> "hide")
hide() {
this.$refs.dialog.hide();
},
onDialogHide() {
// 当 QDialog 触发 "hide" 事件时
// 必须发出此事件
this.$emit("hide");
},
onOKClick() {
// 点击确认时,必须在隐藏 QDialog 之前
// 发出 "ok" 事件(可选传入数据负载)
this.$emit("ok");
// 或带数据负载:this.$emit('ok', { ... })
// 然后隐藏对话框
this.hide();
},
onCancelClick() {
// 只需隐藏对话框即可
this.hide();
},
},
};
</script>Cordova/Capacitor 返回按钮
Quasar 默认会处理返回按钮的行为,使其在有对话框打开时关闭对话框,而不是执行默认的返回上一页操作(那样的用户体验并不好)。
但如果您希望禁用此行为,可以编辑 /quasar.config 文件:
// quasar.config file
return {
framework: {
config: {
capacitor: {
// Quasar 会在按下手机返回按钮时处理应用退出。
backButtonExit: true/false/'*'/['/login', '/home', '/my-page'],
// 另一方面,以下配置会完全
// 禁用 Quasar 的返回按钮管理。
backButton: true/false
}
}
}
}