Skip to page content

选择器

QSelect 组件有两种选择类型:单选或多选。该组件会打开一个菜单用于选择列表和操作。对于较长的列表,还可以使用过滤器。

如果您需要的是下拉"按钮"而不是"输入框",请使用按钮下拉菜单

QSelect API

设计

概览

WARNING

对于 QSelect,您只能使用一种主要设计(filledoutlinedstandoutborderless)。您不能同时使用多种设计,因为它们是互斥的。

装饰器

颜色定制

可清除

作为辅助功能,您可以使用 clearable 属性,这样用户可以通过附加的图标将模型重置为 null。下面示例中的第二个 QSelect 等同于使用 clearable

禁用和只读

带有 type=“submit” 的 QBtn 插槽

WARNING

当在 QField、QInput 或 QSelect 的"before"、“after”、"prepend"或"append"插槽中放置 type=“submit” 的 QBtn 时,您还应该在相关的 QBtn 上添加 @click 监听器。此监听器应调用提交表单的方法。此类插槽中的所有"click"事件都不会传播到其父元素。

菜单过渡效果

WARNING

请注意,使用 options-cover 属性时,过渡效果不起作用。

下面的示例展示了几种过渡效果。有关可用过渡的完整列表,请转到过渡

选项列表显示模式

默认情况下,QSelect 在桌面设备上将选项列表显示为菜单,在移动设备上显示为对话框。您可以使用 behavior 属性强制使用某种行为。

WARNING

请注意,在 iOS 上,菜单行为可能会产生问题,特别是与 use-input 属性结合使用时。您可以使用条件 behavior 属性,如 :behavior="$q.platform.is.ios === true ? 'dialog' : 'menu'" 仅在 iOS 上使用对话框模式。

模型

WARNING

单选的模型可以是任何类型(字符串、对象等),而多选的模型必须是数组。

模型内容可以受 emit-value 属性的影响,您将在下面的"选项"部分了解到这一点。

选项

选项类型

影响模型

使用 emit-value 时,模型将变为指定选定选项中确定的 value。默认是发出整个选项。仅当选项为对象形式时,使用它才有意义。

使用 map-options 时,模型可以只包含 value,它将根据选项映射来确定其标签。这会带来性能损失,因此仅在绝对必要时使用它。例如,如果模型包含整个对象(因此包含标签属性),则不需要它。

自定义属性名称

默认情况下,QSelect 查看选项数组对象中每个选项的 labelvaluedisablesanitize 属性。但您可以覆盖这些:

WARNING

如果您为自定义属性使用函数,请始终检查选项是否为 null。这些函数用于列表中的选项和选定的选项。

自定义菜单选项

WARNING

选项列表使用虚拟滚动渲染,因此如果您为一个选项渲染多个元素,必须在除第一个元素外的所有元素上设置 q-virtual-scroll--with-prev 类。

这是另一个示例,我们为每个选项添加一个 QToggle。可能性是无限的。

默认情况下,当没有选项时,菜单不会出现。但您可以自定义此场景并指定菜单应显示的内容。

懒加载

以下示例展示了如何使用懒加载选项。这意味着,除了其他许多事情外,在第一次渲染时不需要 options 属性。

您可以在滚动到底部时动态加载新选项:

覆盖模式

禁用 TAB 选择

显示值

过滤和自动完成

带有 “use-input” 的原生属性

在 QSelect 上设置的所有不在 API 属性列表中的属性都将传递给用于过滤/自动完成/添加新值的原生输入字段(请先查看 use-input 属性描述以了解它的作用)。一些例子:autocomplete、placeholder。

更多信息:原生输入属性

创建新值

TIP

以下只是一些示例,帮助您开始创建自己的 QSelect 行为。这不是 QSelect 提供的可能性的详尽列表。

将此功能与 use-input 属性一起使用是有意义的。

要启用创建新值,您需要指定 new-value-mode 属性和/或监听 @new-value 事件。如果您同时使用两者,那么监听 @new-value 的目的仅是在自定义场景中覆盖 new-value-mode

new-value-mode 属性

new-value-mode 属性值指定应如何添加值:add(添加值,即使是重复的)、add-unique(仅在不重复时添加)或 toggle(如果模型中尚不存在则添加值,否则将其删除)。

通过使用此属性,您不需要同时监听 @new-value 事件,除非您有一些特定场景需要覆盖行为。

@new-value 事件

@new-value 事件与要添加的值和一个 done 回调一起发出。done 回调有两个可选参数:

  • 要添加的值
  • 行为(与 new-value-mode 属性相同的值,当指定时会覆盖该属性 – 如果使用)-- 默认行为(如果不使用 new-value-mode)是添加值,即使它是重复的

不带参数调用 done() 只会清空输入框值,而不会以任何方式修改模型。

使用菜单和过滤

过滤并将新值添加到菜单:

过滤新值(在下面的示例中,要添加的值需要至少 3 个字符才能通过),并且不添加到菜单:

从输入生成多个值:

净化处理

默认情况下,所有选项(包括选定的选项)都会被净化处理。这意味着以 HTML 格式显示它们的功能被禁用。但是,如果您需要在选项上使用 HTML 并且信任其内容,那么有几种方法可以做到这一点。

您可以通过以下方式强制菜单选项的 HTML 形式:

  • 将受信任选项的 html 键设置为 true(针对特定的受信任选项)
  • 或者设置 QSelect 的 options-html 属性(针对所有选项)

如果满足以下条件,QSelect 的显示值将以 HTML 形式显示:

  • 设置了 QSelect 的 display-value-html 属性
  • 或者您没有使用 display-value 并且
    • 设置了 QSelect 的 options-html 属性
    • 任何选定的选项都将 html 键设置为 true
WARNING

如果您使用 selectedselected-item 插槽,那么您负责对显示值进行净化处理。display-value-html 属性将不适用。

渲染性能

渲染性能不会受到选项数量的太大影响,除非在大型集合上使用 map-options。 注意使用了无限滚动,它会在用户滚动列表时渲染额外的选项。

TIP
  • (组合式 API)要在使用大量选项时获得最佳性能,请不要使用 ref()/computed()/reactive() 等函数包装传递给 options 属性的数组。这允许 Vue 跳过使列表对变化做出"响应"。
  • (选项式 API)要在使用大量选项时获得最佳性能,请使用 Object.freeze(items) 冻结传递给 options 属性的数组。这允许 Vue 跳过使列表对变化做出"响应"。

键盘导航

当 QSelect 获得焦点时:

  • 按下 ENTERARROW DOWN(如果未设置 use-input 则为 SPACE)将打开选项列表
  • 如果设置了 use-chips:
    • 按下 SHIFT + TAB 将向后浏览 QChips(如果选择了 QChip,TAB 将向前浏览 QChips)
    • 当选择了 QChip 时按下 ENTER 将从选择中删除该选项
    • 按下 BACKSPACE 将从选择中删除最后一个选项(当设置了 use-input 时,输入应为空)
  • 当设置了 clearable 时按下 BACKSPACE:
    • 对于单选,它会清除模型(值为 null)
    • 对于多选,它会删除最后添加的值
  • 按下 TAB(或者如果未设置 use-chips 或选择了第一个 QChip,则按下 SHIFT + TAB)将导航到页面上的下一个或上一个可聚焦元素
  • 如果未设置 use-input,键入文本(0 - 9A - Z)将:
    • 创建一个搜索缓冲区(如果 1.5 秒内没有键入新键,将重置),用于在选项标签中搜索
    • 如果多次键入缓冲区中的第一个键,则选择以该字母开头的下一个选项(在当前焦点之后)
    • 选择与键入文本匹配的下一个选项(从当前焦点开始)(匹配是模糊的 - 选项标签应以第一个字母开头并包含所有字母)

你可以通过阻止 QSelect 的 keydown 事件来阻止大部分按键的默认操作;例如 @keydown.enter.prevent 可以阻止 ENTER 打开选项列表。例外的是 ESC,它的处理(关闭选项列表)绑定在 keyup 事件上,无法通过这种方式取消。

当打开选项列表时:

  • 按下 向上箭头向下箭头 将在选项列表中向上或向下导航
  • 按下 PAGE UPPAGE DOWN 将在选项列表中向上或向下导航一页
  • 按下 HOMEEND 将导航到选项列表的开始或结束(仅当您不使用 use-input 或输入为空时)
  • 使用箭头键导航时,当到达列表的开始或结束时,导航将环绕
  • 当在列表中选择了一个选项时,按下 ENTER(或者如果未设置 use-input,则按下 空格,或者如果未设置 multipledisable-tab-selection,则按下 TAB)将:
    • 如果未设置 multipledisable-tab-selection,则选择该选项并关闭选项列表
    • 如果设置了 multiple,则切换该选项

无障碍
v2.25+

QSelect 遵循 WAI-ARIA 组合框模式。焦点目标始终是一个带有 role="combobox"<input> ——当设置了 use-input 时为真实的筛选输入框,否则为一个显示当前选中值的只读输入框,屏幕阅读器可以直接从中读取当前值。无论字段状态如何它都会被渲染,因此始终携带无障碍名称、当前值以及 label 的 for 指向的 idreadonly 的 QSelect 保持其可聚焦并标记为 aria-readonly="true",而 disable 的则留在无障碍树中(通告为不可用)但通过原生 disabled 属性退出 Tab 序列。两者都不能打开弹窗。它携带 aria-expanded 反映弹窗状态,aria-controls 引用选项列表(仅在带选项的弹窗实际存在时才有,确保引用不会指向缺失的元素),aria-activedescendant 追踪高亮选项,以及 aria-autocomplete——当 use-input 允许输入文字筛选选项时为 list,否则为 none。按照该模式,弹窗打开期间焦点始终不会离开此输入框——列表从该输入框操作,按键详见上方的键盘导航章节。

弹窗内容是一个 listbox(始终携带 aria-multiselectable,根据 multiple 属性为 truefalse),其选项携带 aria-selected 以及 aria-setsizearia-posinset:由于列表采用虚拟滚动,任何时刻 DOM 中只有部分选项,这些属性让屏幕阅读器仍能通告每个选项在完整集合中的真实位置。

label 属性同时作为组合框的 aria-label;在 QSelect 上设置的 aria-labelaria-labelledby 属性优先级更高,因为它直接应用到可聚焦控件上(参见"use-input" 的原生属性下的无障碍提示)。两项插槽相关的职责由你负责:使用 option 插槽时,需要在你的选项元素上 v-bind="scope.itemProps",否则选项会丢失 role="option"、id(aria-activedescendant 目标)、aria-selected 和位置属性;before-options/after-options 插槽中的内容位于 listbox 之外且在弹窗打开时无法通过键盘到达,因此避免在那里放置交互元素。标签关联和错误通告继承自字段框架——参见 QField 的无障碍章节

原生表单提交

当处理具有 actionmethod 的原生表单时(例如,将 Quasar 与 ASP.NET 控制器一起使用时),您需要在 QSelect 上指定 name 属性,否则 formData 将不包含它(如果应该包含) - 所有值都转换为字符串(原生行为,因此不要使用对象值):