Quasar 对话框是让用户能够选择特定操作或操作列表的绝佳方式。它们还可以向用户提供重要信息,或要求他们做出一个或多个决定。
¥Quasar Dialogs are a great way to offer the user the ability to choose a specific action or list of actions. They also can provide the user with important information, or require them to make a decision (or multiple decisions).
从 UI 的角度来看,你可以将对话框视为一种浮动模式,它只覆盖屏幕的一部分。这意味着对话框应该仅用于快速用户操作。
¥From a UI perspective, you can think of Dialogs as a type of floating modal, which covers only a portion of the screen. This means Dialogs should only be used for quick user actions.
提示
对话框也可以用作 Vue 文件模板中的组件(用于复杂的用例,例如特定的表单组件、可选选项等)。为此,请转到 QDialog 页面。
¥Dialogs can also be used as a component in your Vue file templates (for complex use-cases, like specific form components, selectable options, etc.). For this, go to QDialog page.
与 QDialog 组件相比,使用对话框作为 Quasar 插件的优势在于,该插件也可以从 Vue 空间外部调用,并且不需要你管理其模板。因此,它们的自定义设置无法与组件版本进行比较。
¥The advantage of using Dialogs as Quasar Plugins as opposed to QDialog component is that the plugin can also be called from outside of Vue space and doesn’t require you to manage their templates. But as a result, their customization cannot be compared to their component counterpart.
但是,你也可以为对话框插件提供一个组件来渲染(参见 “调用自定义组件” 部分),这是一种避免内联对话框使你的 Vue 模板混乱的好方法(它还可以帮助你更好地组织项目文件并重用对话框)。
¥However, you can also supply a component for the Dialog Plugin to render (see the “Invoking custom component” section) which is a great way to avoid cluttering your Vue templates with inline dialogs (and it will also help you better organize your project files and also reuse dialogs).
使用 QDialog 插件,你可以以编程方式构建三种类型的对话框,表单内容如下:
¥With the QDialog plugin, you can programmatically build three types of dialogs with the following form content:
提示对话框 - 要求用户在输入字段中填写某种数据。
¥A prompt dialog - asking the user to fill in some sort of data in an input field.
一组选项,供用户使用单选按钮或切换按钮(仅限单选)或复选框(用于多选)进行选择。
¥A set of options for the user to select from using either radio buttons or toggles (singular selection only) or check boxes (for multiple selections).
一个简单的确认对话框,用户可以在其中取消或为特定操作或输入提供 “ok”。
¥A simple confirmation dialog, where the user can cancel or give their “ok” for a particular action or input.
在为了创建 #1(提示输入表单),你需要在 opts
对象中添加 prompt
属性。
¥In order to create #1, the prompting input form, you have the prompt
property within the opts
object.
为了创建 #2(选项选择表单),你需要在 opts
对象中添加 options
属性。
¥In order to create #2, the options selection form, you have the options
property within the opts
object.
// quasar.config file
return {
framework: {
plugins: [
'Dialog'
]
}
}
内置组件(Built-in component)
¥Built-in component
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 卡片以了解返回的对象是什么。
¥Please check the API card to see what the returned Object is.
用法(Usage)
¥Usage
提示
对于以下所有示例,请在查看时同时查看浏览器控制台。
¥For all the examples below, also see the browser console while you check them out.
警告
这并不是使用对话框作为 Quasar 插件可以实现的功能的详尽列表。如需进一步了解,请查看 API 部分。
¥This is not an exhaustive list of what you can do with Dialogs as Quasar Plugins. For further exploration check out the API section.
原生属性(Native attributes)
¥Native attributes
你还可以为内部 QInput 或 QOptionGroup 组件提供原生 HTML 属性,如下例所示。
¥You can also supply native HTML attributes to the inner QInput or QOptionGroup components, like in the example below.
用户输入验证(User input validation)
¥User input validation
你可以使用一个基本的验证系统,这样用户在填写预期值之前将无法提交对话框(点击/轻触 “OK” 或按下 ENTER)。
¥There is a basic validation system that you can use so that the user won’t be able to submit the dialog (click/tap on “OK” or press ENTER) until the expected values are filled in.
进度(Progress)
¥Progress
使用 HTML(Using HTML)
¥Using HTML
如果指定了 html: true
属性,则可以在标题和消息中使用 HTML。请注意,这可能会导致 XSS 攻击,因此请确保你自行清理消息。
¥You can use HTML on title and message if you specify the html: true
prop. Please note that this can lead to XSS attacks, so make sure that you sanitize the message by yourself.
调用自定义组件(Invoking custom component)
¥Invoking custom component
你还可以调用自己的自定义组件,而不是依赖 Dialog 插件开箱即用的默认组件。但在这种情况下,你将负责处理所有事情(包括你自己的组件 props)。
¥You can also invoke your own custom component rather than relying on the default one that the Dialog plugin comes with out of the box. But in this case you will be responsible for handling everything (including your own component props).
此功能实际上是 Dialog 插件的 “bread and butter”。它可以帮助你轻松分离和重用对话框的功能,从而保持其他 Vue 组件 HTML 模板的整洁。
¥This feature is actually the “bread and butter” of the Dialog plugin. It helps you keep your other vue components html templates clean by separating and reusing your dialog’s functionality with ease.
触发自定义组件(Triggering the custom component)
¥Triggering the custom component
/**
* 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')
})
使用 Options API 实现上述操作的等效方法是直接使用 this.$q.dialog({ ... })
。
¥The equivalent of the above with Options API is by directly using this.$q.dialog({ ... })
.
警告
但是,你的自定义组件必须遵循下面描述的接口才能完美地连接到 Dialog 插件。请注意 “REQUIRED” 的注释,并按原样使用 - 这只是一个简单示例,仅此而已。
¥Your custom component however must follow the interface described below in order to perfectly hook into the Dialog plugin. Notice the “REQUIRED” comments and take it as is – just a bare-bone example, nothing more.
编写自定义组件(Writing the custom component)
¥Writing the custom component
使用 “脚本设置” 和 Composition API 变体的 SFC(SFC with “script setup” and Composition API variant)
¥SFC with “script setup” and Composition API variant
我们将使用 useDialogPluginComponent 可组合项。
¥We will be using the useDialogPluginComponent composable.
<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+):
¥If you want to define emits
in Object form, then (requires Quasar v2.2.5+):
defineEmits({
// REQUIRED; need to specify some events that your
// component will emit through useDialogPluginComponent()
...useDialogPluginComponent.emitsObject,
// ...your own definitions
})
使用 “script” 和 Composition API 变体的 SFC(SFC with “script” and Composition API variant)
¥SFC with “script” and Composition API variant
我们将使用 useDialogPluginComponent 可组合项。
¥We will be using the useDialogPluginComponent composable.
<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+):
¥If you want to define emits
in Object form, then (requires Quasar v2.2.5+):
emits: {
// REQUIRED; need to specify some events that your
// component will emit through useDialogPluginComponent()
...useDialogPluginComponent.emitsObject,
// ...your own definitions
}
使用 “script” 和 Options API 变体(SFC with “script” and Options API variant)
¥SFC with “script” and Options API variant
<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 返回按钮(Cordova/Capacitor back button)
¥Cordova/Capacitor back button
Quasar 默认会为你处理返回按钮,因此它可以隐藏所有打开的对话框,而不是像默认行为那样返回上一页(这不是一个好的用户体验)。
¥Quasar handles the back button for you by default so it can hide any opened Dialogs instead of the default behavior which is to return to the previous page (which is not a nice user experience).
但是,如果你希望禁用此行为,请编辑你的 /quasar.config
文件:
¥However, should you wish to disable this behavior, edit your /quasar.config
file:
// 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
}
}
}
}