为什么捐赠
API 资源管理器
对话框插件

Quasar 对话框是为用户提供选择特定操作或操作列表的绝佳方式。它们还可以为用户提供重要信息,或要求他们做出决定(或多个决定)。

从 UI 的角度来看,您可以将对话框视为一种浮动模态,它只覆盖屏幕的一部分。这意味着对话框只应用于快速用户操作。

提示

对话框也可以用作 Vue 文件模板中的组件(对于复杂用例,例如特定表单组件、可选选项等)。为此,请转到 QDialog 页面。

使用对话框作为 Quasar 插件而不是 QDialog 组件的优点是,插件也可以从 Vue 空间之外调用,并且不需要您管理它们的模板。但结果是,它们的自定义程度无法与它们的组件对应部分相媲美。

但是,您也可以为对话框插件提供要渲染的组件(参见“调用自定义组件”部分),这是一种避免在 Vue 模板中使用内联对话框的绝佳方法(它还有助于您更好地组织项目文件,并重复使用对话框)。

使用 QDialog 插件,您可以使用以下表单内容以编程方式构建三种类型的对话框

  1. 一个提示对话框 - 询问用户在输入字段中填写一些数据。
  2. 一组选项,供用户使用单选按钮或切换按钮(仅单选)或复选框(多选)进行选择。
  3. 一个简单的确认对话框,用户可以取消或对特定操作或输入给出“确定”。

为了创建 #1,即提示输入表单,您在 opts 对象中拥有 prompt 属性。

为了创建 #2,即选项选择表单,您在 opts 对象中拥有 options 属性。

正在加载对话框 API...
安装

// quasar.config file

return {
  framework: {
    plugins: [
      'Dialog'
    ]
  }
}

内置组件

在 Vue 文件之外

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 攻击,因此请确保您自己对消息进行消毒。

不安全的 HTML 消息



调用自定义组件

您也可以调用自己的自定义组件,而不是依赖对话框插件开箱即用的默认组件。但在这种情况下,您将负责处理所有内容(包括您自己的组件道具)。

此功能实际上是对话框插件的“核心”。它通过轻松地分离和重复使用对话框的功能来帮助您保持其他 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
      }
    }
  }
}