Quasar 对话框是为用户提供选择特定操作或操作列表的绝佳方式。它们还可以为用户提供重要信息,或要求他们做出决定(或多个决定)。
从 UI 的角度来看,您可以将对话框视为一种浮动模态,它只覆盖屏幕的一部分。这意味着对话框只应用于快速用户操作。
提示
对话框也可以用作 Vue 文件模板中的组件(对于复杂用例,例如特定表单组件、可选选项等)。为此,请转到 QDialog 页面。
使用对话框作为 Quasar 插件而不是 QDialog 组件的优点是,插件也可以从 Vue 空间之外调用,并且不需要您管理它们的模板。但结果是,它们的自定义程度无法与它们的组件对应部分相媲美。
但是,您也可以为对话框插件提供要渲染的组件(参见“调用自定义组件”部分),这是一种避免在 Vue 模板中使用内联对话框的绝佳方法(它还有助于您更好地组织项目文件,并重复使用对话框)。
使用 QDialog 插件,您可以使用以下表单内容以编程方式构建三种类型的对话框
- 一个提示对话框 - 询问用户在输入字段中填写一些数据。
- 一组选项,供用户使用单选按钮或切换按钮(仅单选)或复选框(多选)进行选择。
- 一个简单的确认对话框,用户可以取消或对特定操作或输入给出“确定”。
为了创建 #1,即提示输入表单,您在 opts
对象中拥有 prompt
属性。
为了创建 #2,即选项选择表单,您在 opts
对象中拥有 options
属性。
// quasar.config file
return {
framework: {
plugins: [
'Dialog'
]
}
}
内置组件
import { Dialog } from 'quasar'
(Object) Dialog.create({ ... })
// inside of a Vue file
import { useQuasar } from 'quasar'
setup () {
const $q = useQuasar()
$q.dialog({ ... }) // returns Object
}
请查看 API 卡以查看返回的对象是什么。
用法
提示
对于以下所有示例,在您查看它们时也请查看浏览器控制台。
警告
这不是您对对话框作为 Quasar 插件所能做的一切的详尽列表。要进一步探索,请查看 API 部分。
原生属性
您还可以将原生 HTML 属性提供给内部 QInput 或 QOptionGroup 组件,如下面的示例所示。
用户输入验证
有一个基本验证系统,您可以使用它,这样用户将无法提交对话框(点击/点击“确定”或按 ENTER),直到填写了预期值。
进度
使用 HTML
如果您指定 html: true
属性,则可以使用 HTML 在标题和消息中使用。请注意,这会导致 XSS 攻击,因此请确保您自己对消息进行消毒。
调用自定义组件
您也可以调用自己的自定义组件,而不是依赖对话框插件开箱即用的默认组件。但在这种情况下,您将负责处理所有内容(包括您自己的组件道具)。
此功能实际上是对话框插件的“核心”。它通过轻松地分离和重复使用对话框的功能来帮助您保持其他 vue 组件的 html 模板整洁。
触发自定义组件
/**
* This way of using it can reside outside
* of a Vue component as well
*/
import { Dialog } from 'quasar'
import CustomComponent from '..path.to.component..'
Dialog.create({
component: CustomComponent,
// props forwarded to your custom component
componentProps: {
text: 'something',
persistent: true,
// ...more..props...
}
}).onOk(() => {
console.log('OK')
}).onCancel(() => {
console.log('Cancel')
}).onDismiss(() => {
console.log('Called on OK or Cancel')
})
上面使用选项 API 的等效项是直接使用 this.$q.dialog({ ... })
。
警告
但是,您的自定义组件必须遵循下面描述的接口,才能完美地挂钩到对话框插件。注意“必需”注释,并将其作为是 - 只是一个最简单的示例,仅此而已。
编写自定义组件
使用“script setup”和组合式 API 的单文件组件
我们将使用 useDialogPluginComponent 组合式 API。
<template>
<q-dialog ref="dialogRef" @hide="onDialogHide">
<q-card class="q-dialog-plugin">
<!--
...content
... use q-card-section for it?
-->
<!-- buttons example -->
<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({
// ...your custom props
})
defineEmits([
// REQUIRED; need to specify some events that your
// component will emit through useDialogPluginComponent()
...useDialogPluginComponent.emits
])
const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } = useDialogPluginComponent()
// dialogRef - Vue ref to be applied to QDialog
// onDialogHide - Function to be used as handler for @hide on QDialog
// onDialogOK - Function to call to settle dialog with "ok" outcome
// example: onDialogOK() - no payload
// example: onDialogOK({ /*...*/ }) - with payload
// onDialogCancel - Function to call to settle dialog with "cancel" outcome
// this is part of our example (so not required)
function onOKClick () {
// on OK, it is REQUIRED to
// call onDialogOK (with optional payload)
onDialogOK()
// or with payload: onDialogOK({ ... })
// ...and it will also hide the dialog automatically
}
</script>
如果您想以对象形式定义 emits
,则(需要 Quasar v2.2.5+)
defineEmits({
// REQUIRED; need to specify some events that your
// component will emit through useDialogPluginComponent()
...useDialogPluginComponent.emitsObject,
// ...your own definitions
})
使用“script”和组合式 API 的单文件组件
我们将使用 useDialogPluginComponent 组合式 API。
<template>
<!-- notice dialogRef here -->
<q-dialog ref="dialogRef" @hide="onDialogHide">
<q-card class="q-dialog-plugin">
<!--
...content
... use q-card-section for it?
-->
<!-- buttons example -->
<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: {
// ...your custom props
},
emits: [
// REQUIRED; need to specify some events that your
// component will emit through useDialogPluginComponent()
...useDialogPluginComponent.emits
],
setup () {
// REQUIRED; must be called inside of setup()
const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } = useDialogPluginComponent()
// dialogRef - Vue ref to be applied to QDialog
// onDialogHide - Function to be used as handler for @hide on QDialog
// onDialogOK - Function to call to settle dialog with "ok" outcome
// example: onDialogOK() - no payload
// example: onDialogOK({ /*.../* }) - with payload
// onDialogCancel - Function to call to settle dialog with "cancel" outcome
return {
// This is REQUIRED;
// Need to inject these (from useDialogPluginComponent() call)
// into the vue scope for the vue html template
dialogRef,
onDialogHide,
// other methods that we used in our vue html template;
// these are part of our example (so not required)
onOKClick () {
// on OK, it is REQUIRED to
// call onDialogOK (with optional payload)
onDialogOK()
// or with payload: onDialogOK({ ... })
// ...and it will also hide the dialog automatically
},
// we can passthrough onDialogCancel directly
onCancelClick: onDialogCancel
}
}
}
</script>
如果您想以对象形式定义 emits
,则(需要 Quasar v2.2.5+)
emits: {
// REQUIRED; need to specify some events that your
// component will emit through useDialogPluginComponent()
...useDialogPluginComponent.emitsObject,
// ...your own definitions
}
使用“script”和选项式 API 的单文件组件
<template>
<q-dialog ref="dialog" @hide="onDialogHide">
<q-card class="q-dialog-plugin">
<!--
...content
... use q-card-section for it?
-->
<!-- buttons example -->
<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: {
// ...your custom props
},
emits: [
// REQUIRED
'ok', 'hide'
],
methods: {
// following method is REQUIRED
// (don't change its name --> "show")
show () {
this.$refs.dialog.show()
},
// following method is REQUIRED
// (don't change its name --> "hide")
hide () {
this.$refs.dialog.hide()
},
onDialogHide () {
// required to be emitted
// when QDialog emits "hide" event
this.$emit('hide')
},
onOKClick () {
// on OK, it is REQUIRED to
// emit "ok" event (with optional payload)
// before hiding the QDialog
this.$emit('ok')
// or with payload: this.$emit('ok', { ... })
// then hiding dialog
this.hide()
},
onCancelClick () {
// we just need to hide the dialog
this.hide()
}
}
}
</script>
Cordova/Capacitor 返回按钮
Quasar 默认情况下会为您处理返回按钮,因此它可以隐藏任何打开的对话框,而不是默认的行为,即返回到上一页(这不是良好的用户体验)。
但是,如果您希望禁用此行为,请编辑您的 /quasar.config
文件
// quasar.config file
return {
framework: {
config: {
capacitor: {
// Quasar handles app exit on mobile phone back button.
backButtonExit: true/false/'*'/['/login', '/home', '/my-page'],
// On the other hand, the following completely
// disables Quasar's back button management.
backButton: true/false
}
}
}
}