Field
QField 组件提供了表单组件的通用方法,它可以使用 :model-value
(或者 v-model
,如果您要使用 clearable
的话)来绑定组件内的数据。还支持设置标签,提示信息,错误验证以及一系列的样式和颜色。
QField 允许您在其中展示任意的表单控件(实际上任何内容都可以),只需要将其放在 control
插槽中即可。
WARNING
不要再使用 QField 封装 QInput, QFile 或 QSelect,因为它们已经继承了 QField。
QField API
Design
TIP
下面的示例使用简单的文本内容只是为了向您展示 QField 可以使用的外观设计。要查看封装真实组件的示例,请参见“基本功能”部分。
WARNING
QField 不会(也不应该)管理您的 control
插槽内容,所以如果您在使用 label
属性,那么最好也声明一下stack-label
属性,否则,当 QField 未聚焦时,它可能会与您的控件重叠。
预览
您只能给 QField 使用一种主要的外观设计款式(filled
, outlined
, standout
, borderless
),不能使用多个,因为它们是互相排斥的。
<template>
<div class="q-pa-md">
<div class="q-gutter-md" style="max-width: 300px">
<q-field label="Standard" stack-label>
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">Field content</div>
</template>
</q-field>
<q-field filled label="Filled" stack-label>
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">Field content</div>
</template>
</q-field>
<q-field outlined label="Outlined" stack-label>
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">Field content</div>
</template>
</q-field>
<q-field standout label="Standout" stack-label>
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">Field content</div>
</template>
</q-field>
<q-field standout="bg-teal text-white" label="Custom standout" stack-label>
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">Field content</div>
</template>
</q-field>
<q-field borderless label="Borderless" stack-label>
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">Field content</div>
</template>
</q-field>
<q-field rounded filled label="Rounded filled" stack-label>
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">Field content</div>
</template>
</q-field>
<q-field rounded outlined label="Rounded outlined" stack-label>
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">Field content</div>
</template>
</q-field>
<q-field rounded standout label="Rounded standout" stack-label>
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">Field content</div>
</template>
</q-field>
<q-field square filled label="Square filled" stack-label>
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">Field content</div>
</template>
</q-field>
<q-field square outlined label="Square outlined" stack-label>
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">Field content</div>
</template>
</q-field>
<q-field square standout label="Square standout" stack-label>
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">Field content</div>
</template>
</q-field>
</div>
</div>
</template>
着色
<template>
<div class="q-pa-md">
<div class="q-gutter-y-md column" style="max-width: 300px">
<q-field color="purple-12" label="Label" stack-label>
<template v-slot:prepend>
<q-icon name="event" />
</template>
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{text}}</div>
</template>
</q-field>
<q-field color="teal" filled label="Label" stack-label>
<template v-slot:prepend>
<q-icon name="event" />
</template>
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{text}}</div>
</template>
</q-field>
<q-field color="grey-3" label-color="orange" outlined label="Label" stack-label>
<template v-slot:append>
<q-icon name="event" color="orange" />
</template>
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{text}}</div>
</template>
</q-field>
<q-field color="lime-11" bg-color="green" filled label="Label" stack-label>
<template v-slot:prepend>
<q-icon name="event" />
</template>
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{text}}</div>
</template>
</q-field>
<q-field color="teal" outlined label="Label" stack-label>
<template v-slot:append>
<q-avatar>
<img src="https://cdn.quasar.dev/logo-v2/svg/logo.svg">
</q-avatar>
</template>
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{text}}</div>
</template>
</q-field>
<q-field color="orange" standout bottom-slots :model-value="text" label="Label" stack-label counter clearable>
<template v-slot:prepend>
<q-icon name="place" />
</template>
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{text}}</div>
</template>
<template v-slot:append>
<q-icon name="favorite" />
</template>
<template v-slot:hint>
Field hint
</template>
</q-field>
</div>
</div>
</template>
Standard-标准
<template>
<div class="q-pa-md">
<div class="q-gutter-y-md column" style="max-width: 300px">
<q-toggle v-model="dense" label="Dense QField" />
<q-field :dense="dense">
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{text}}</div>
</template>
</q-field>
<q-field label="Label" stack-label :dense="dense">
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{text}}</div>
</template>
</q-field>
<q-field :dense="dense">
<template v-slot:prepend>
<q-icon name="event" />
</template>
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{text}}</div>
</template>
</q-field>
<q-field :dense="dense">
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{text}}</div>
</template>
<template v-slot:append>
<q-avatar>
<img src="https://cdn.quasar.dev/logo-v2/svg/logo.svg">
</q-avatar>
</template>
</q-field>
<q-field :model-value="text" bottom-slots label="Label" stack-label counter :dense="dense">
<template v-slot:prepend>
<q-icon name="place" />
</template>
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{text}}</div>
</template>
<template v-slot:append>
<q-icon name="close" class="cursor-pointer" />
</template>
<template v-slot:hint>
Field hint
</template>
</q-field>
<q-field :model-value="text" bottom-slots label="Label" stack-label counter maxlength="12" :dense="dense">
<template v-slot:before>
<q-icon name="flight_takeoff" />
</template>
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{text}}</div>
</template>
<template v-slot:append>
<q-icon v-if="text !== ''" name="close" class="cursor-pointer" />
<q-icon name="search" />
</template>
<template v-slot:hint>
Field hint
</template>
</q-field>
<q-field :model-value="text" bottom-slots label="Label" stack-label counter maxlength="12" :dense="dense">
<template v-slot:before>
<q-avatar>
<img src="https://cdn.quasar.dev/img/avatar5.jpg">
</q-avatar>
</template>
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{text}}</div>
</template>
<template v-slot:append>
<q-icon v-if="text !== ''" name="close" class="cursor-pointer" />
<q-icon name="schedule" />
</template>
<template v-slot:hint>
Field hint
</template>
<template v-slot:after>
<q-btn round dense flat icon="send" />
</template>
</q-field>
<q-field :model-value="text" bottom-slots label="Label" stack-label counter maxlength="12" :dense="dense">
<template v-slot:before>
<q-icon name="event" />
</template>
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{text}}</div>
</template>
<template v-slot:hint>
Field hint
</template>
<template v-slot:append>
<q-btn round dense flat icon="add" />
</template>
</q-field>
<q-field hint="Disable" :dense="dense" disable>
<template v-slot:control>
<div class="self-center full-width no-outline">{{text}}</div>
</template>
</q-field>
<q-field hint="Readonly" :dense="dense" readonly>
<template v-slot:control>
<div class="self-center full-width no-outline">{{text}}</div>
</template>
</q-field>
<q-field hint="Disable and readonly" :dense="dense" disable readonly>
<template v-slot:control>
<div class="self-center full-width no-outline">{{text}}</div>
</template>
</q-field>
</div>
</div>
</template>
Filled-填充
<template>
<div class="q-pa-md">
<div class="q-gutter-y-md column" style="max-width: 300px">
<q-toggle v-model="dense" label="Dense QField" />
<q-field filled :dense="dense">
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{text}}</div>
</template>
</q-field>
<q-field filled label="Label" stack-label :dense="dense">
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{text}}</div>
</template>
</q-field>
<q-field filled square hint="With perfect square borders" :dense="dense">
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{text}}</div>
</template>
</q-field>
<q-field filled :dense="dense">
<template v-slot:prepend>
<q-icon name="event" />
</template>
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{text}}</div>
</template>
</q-field>
<q-field filled :dense="dense">
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{text}}</div>
</template>
<template v-slot:append>
<q-avatar>
<img src="https://cdn.quasar.dev/logo-v2/svg/logo.svg">
</q-avatar>
</template>
</q-field>
<q-field filled :model-value="text" bottom-slots label="Label" stack-label counter :dense="dense">
<template v-slot:prepend>
<q-icon name="place" />
</template>
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{text}}</div>
</template>
<template v-slot:append>
<q-icon name="close" class="cursor-pointer" />
</template>
<template v-slot:hint>
Field hint
</template>
</q-field>
<q-field filled :model-value="text" bottom-slots label="Label" stack-label counter maxlength="12" :dense="dense">
<template v-slot:before>
<q-icon name="flight_takeoff" />
</template>
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{text}}</div>
</template>
<template v-slot:append>
<q-icon v-if="text !== ''" name="close" class="cursor-pointer" />
<q-icon name="search" />
</template>
<template v-slot:hint>
Field hint
</template>
</q-field>
<q-field filled :model-value="text" bottom-slots label="Label" stack-label counter maxlength="12" :dense="dense">
<template v-slot:before>
<q-avatar>
<img src="https://cdn.quasar.dev/img/avatar5.jpg">
</q-avatar>
</template>
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{text}}</div>
</template>
<template v-slot:append>
<q-icon v-if="text !== ''" name="close" class="cursor-pointer" />
<q-icon name="schedule" />
</template>
<template v-slot:hint>
Field hint
</template>
<template v-slot:after>
<q-btn round dense flat icon="send" />
</template>
</q-field>
<q-field filled :model-value="text" bottom-slots label="Label" stack-label counter maxlength="12" :dense="dense">
<template v-slot:before>
<q-icon name="event" />
</template>
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{text}}</div>
</template>
<template v-slot:hint>
Field hint
</template>
<template v-slot:append>
<q-btn round dense flat icon="add" />
</template>
</q-field>
<q-field filled hint="Disable" :dense="dense" disable>
<template v-slot:control>
<div class="self-center full-width no-outline">{{text}}</div>
</template>
</q-field>
<q-field filled hint="Readonly" :dense="dense" readonly>
<template v-slot:control>
<div class="self-center full-width no-outline">{{text}}</div>
</template>
</q-field>
<q-field filled hint="Disable and readonly" :dense="dense" disable readonly>
<template v-slot:control>
<div class="self-center full-width no-outline">{{text}}</div>
</template>
</q-field>
</div>
</div>
</template>
Outlined-轮廓
<template>
<div class="q-pa-md">
<div class="q-gutter-y-md column" style="max-width: 300px">
<q-toggle v-model="dense" label="Dense QField" />
<q-field outlined :dense="dense">
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{text}}</div>
</template>
</q-field>
<q-field outlined label="Label" stack-label :dense="dense">
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{text}}</div>
</template>
</q-field>
<q-field outlined square hint="With perfect square borders" :dense="dense">
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{text}}</div>
</template>
</q-field>
<q-field outlined :dense="dense">
<template v-slot:prepend>
<q-icon name="event" />
</template>
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{text}}</div>
</template>
</q-field>
<q-field outlined :dense="dense">
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{text}}</div>
</template>
<template v-slot:append>
<q-avatar>
<img src="https://cdn.quasar.dev/logo-v2/svg/logo.svg">
</q-avatar>
</template>
</q-field>
<q-field outlined :model-value="text" bottom-slots label="Label" stack-label counter :dense="dense">
<template v-slot:prepend>
<q-icon name="place" />
</template>
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{text}}</div>
</template>
<template v-slot:append>
<q-icon name="close" class="cursor-pointer" />
</template>
<template v-slot:hint>
Field hint
</template>
</q-field>
<q-field outlined :model-value="text" bottom-slots label="Label" stack-label counter maxlength="12" :dense="dense">
<template v-slot:before>
<q-icon name="flight_takeoff" />
</template>
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{text}}</div>
</template>
<template v-slot:append>
<q-icon v-if="text !== ''" name="close" class="cursor-pointer" />
<q-icon name="search" />
</template>
<template v-slot:hint>
Field hint
</template>
</q-field>
<q-field outlined :model-value="text" bottom-slots label="Label" stack-label counter maxlength="12" :dense="dense">
<template v-slot:before>
<q-avatar>
<img src="https://cdn.quasar.dev/img/avatar5.jpg">
</q-avatar>
</template>
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{text}}</div>
</template>
<template v-slot:append>
<q-icon v-if="text !== ''" name="close" class="cursor-pointer" />
<q-icon name="schedule" />
</template>
<template v-slot:hint>
Field hint
</template>
<template v-slot:after>
<q-btn round dense flat icon="send" />
</template>
</q-field>
<q-field outlined :model-value="text" bottom-slots label="Label" stack-label counter maxlength="12" :dense="dense">
<template v-slot:before>
<q-icon name="event" />
</template>
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{text}}</div>
</template>
<template v-slot:hint>
Field hint
</template>
<template v-slot:append>
<q-btn round dense flat icon="add" />
</template>
</q-field>
<q-field outlined hint="Disable" :dense="dense" disable>
<template v-slot:control>
<div class="self-center full-width no-outline">{{text}}</div>
</template>
</q-field>
<q-field outlined hint="Readonly" :dense="dense" readonly>
<template v-slot:control>
<div class="self-center full-width no-outline">{{text}}</div>
</template>
</q-field>
<q-field outlined hint="Disable and readonly" :dense="dense" disable readonly>
<template v-slot:control>
<div class="self-center full-width no-outline">{{text}}</div>
</template>
</q-field>
</div>
</div>
</template>
Standout-突出
<template>
<div class="q-pa-md">
<div class="q-gutter-y-md column" style="max-width: 300px">
<q-toggle v-model="dense" label="Dense QInput" />
<q-field standout :dense="dense">
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{text}}</div>
</template>
</q-field>
<q-field standout label="Label" stack-label :dense="dense">
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{text}}</div>
</template>
</q-field>
<q-field standout="bg-teal text-white" label="Custom standout" stack-label :dense="dense">
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{text}}</div>
</template>
</q-field>
<q-field standout square hint="With perfect square borders" :dense="dense">
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{text}}</div>
</template>
</q-field>
<q-field standout :dense="dense">
<template v-slot:prepend>
<q-icon name="event" />
</template>
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{text}}</div>
</template>
</q-field>
<q-field standout :dense="dense">
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{text}}</div>
</template>
<template v-slot:append>
<q-avatar>
<img src="https://cdn.quasar.dev/logo-v2/svg/logo.svg">
</q-avatar>
</template>
</q-field>
<q-field standout :model-value="text" bottom-slots label="Label" stack-label counter :dense="dense">
<template v-slot:prepend>
<q-icon name="place" />
</template>
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{text}}</div>
</template>
<template v-slot:append>
<q-icon name="close" class="cursor-pointer" />
</template>
<template v-slot:hint>
Field hint
</template>
</q-field>
<q-field standout :model-value="text" bottom-slots label="Label" stack-label counter maxlength="12" :dense="dense">
<template v-slot:before>
<q-icon name="flight_takeoff" />
</template>
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{text}}</div>
</template>
<template v-slot:append>
<q-icon v-if="text !== ''" name="close" class="cursor-pointer" />
<q-icon name="search" />
</template>
<template v-slot:hint>
Field hint
</template>
</q-field>
<q-field standout :model-value="text" bottom-slots label="Label" stack-label counter maxlength="12" :dense="dense">
<template v-slot:before>
<q-avatar>
<img src="https://cdn.quasar.dev/img/avatar5.jpg">
</q-avatar>
</template>
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{text}}</div>
</template>
<template v-slot:append>
<q-icon v-if="text !== ''" name="close" class="cursor-pointer" />
<q-icon name="schedule" />
</template>
<template v-slot:hint>
Field hint
</template>
<template v-slot:after>
<q-btn round dense flat icon="send" />
</template>
</q-field>
<q-field standout :model-value="text" bottom-slots label="Label" stack-label counter maxlength="12" :dense="dense">
<template v-slot:before>
<q-icon name="event" />
</template>
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{text}}</div>
</template>
<template v-slot:hint>
Field hint
</template>
<template v-slot:append>
<q-btn round dense flat icon="add" />
</template>
</q-field>
<q-field standout hint="Disable" :dense="dense" disable>
<template v-slot:control>
<div class="self-center full-width no-outline">{{text}}</div>
</template>
</q-field>
<q-field standout hint="Readonly" :dense="dense" readonly>
<template v-slot:control>
<div class="self-center full-width no-outline">{{text}}</div>
</template>
</q-field>
<q-field standout hint="Disable and readonly" :dense="dense" disable readonly>
<template v-slot:control>
<div class="self-center full-width no-outline">{{text}}</div>
</template>
</q-field>
</div>
</div>
</template>
其中一个很合适的的用例就是将 Standout 模式的 QField 用在 QToolbar 中:
<template>
<div class="q-pa-md">
<div class="q-gutter-y-md column" style="width: 300px; max-width: 100%">
<q-toolbar class="bg-primary text-white rounded-borders">
<q-btn round dense flat icon="menu" class="q-mr-xs" />
<q-avatar class="gt-xs">
<img src="https://cdn.quasar.dev/logo-v2/svg/logo-mono-white.svg">
</q-avatar>
<q-space />
<q-field dark dense standout>
<template v-slot:control>
<div class="self-center no-outline" tabindex="0">Time is {{value}}</div>
</template>
<template v-slot:append>
<q-btn flat round dense :disable="value < 10" icon="replay_10" @click.stop="value -= 10" />
<q-btn flat round dense :disable="value > 90" icon="forward_10" @click.stop="value += 10" />
</template>
</q-field>
</q-toolbar>
</div>
</div>
</template>
Borderless-无边框
无边框(borderless
)设计允许您无缝地将 QField 集成到其他组件中,而无需 QField 在其周围绘制边框或更改其背景颜色:
<template>
<div class="q-pa-md">
<div class="q-gutter-y-md column" style="width: 300px; max-width: 100%">
<q-toolbar class="bg-primary text-white rounded-borders">
<q-btn round dense flat icon="menu" class="q-mr-xs" />
<q-avatar class="gt-xs">
<img src="https://cdn.quasar.dev/logo-v2/svg/logo-mono-white.svg">
</q-avatar>
<q-space />
<q-field dark borderless>
<template v-slot:control>
<div class="self-center no-outline" tabindex="0">Time is {{ value }}</div>
</template>
<template v-slot:append>
<q-btn color="white" flat round dense :disable="value < 10" icon="replay_10" @click.stop="value -= 10" />
<q-btn color="white" flat round dense :disable="value > 90" icon="forward_10" @click.stop="value += 10" />
</template>
</q-field>
</q-toolbar>
</div>
</div>
</template>
圆形边框
圆形(rounded
)属性只能与填充,轮廓和突出的设计(Filled, Outlined 和 Standout )一起工作,如下面的例子所示:
<template>
<div class="q-pa-md">
<div class="q-gutter-y-md column" style="max-width: 300px">
<q-field rounded filled>
<template v-slot:prepend>
<q-icon name="event" />
</template>
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{text}}</div>
</template>
</q-field>
<q-field rounded outlined>
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{text}}</div>
</template>
<template v-slot:append>
<q-avatar>
<img src="https://cdn.quasar.dev/logo-v2/svg/logo.svg">
</q-avatar>
</template>
</q-field>
<q-field rounded standout bottom-slots :model-value="text" label="Label" stack-label counter>
<template v-slot:prepend>
<q-icon name="place" />
</template>
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{text}}</div>
</template>
<template v-slot:append>
<q-icon name="close" class="cursor-pointer" />
</template>
<template v-slot:hint>
Field hint
</template>
</q-field>
</div>
</div>
</template>
方形边框
方形(square
)属性只能与填充,轮廓和突出的设计(Filled, Outlined 和 Standout )一起工作,如下面的例子所示:
<template>
<div class="q-pa-md">
<div class="q-gutter-y-md column" style="max-width: 300px">
<q-field square filled>
<template v-slot:prepend>
<q-icon name="event" />
</template>
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{text}}</div>
</template>
</q-field>
<q-field square outlined>
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{text}}</div>
</template>
<template v-slot:append>
<q-avatar>
<img src="https://cdn.quasar.dev/logo-v2/svg/logo.svg">
</q-avatar>
</template>
</q-field>
<q-field square standout bottom-slots :model-value="text" label="Label" stack-label counter>
<template v-slot:prepend>
<q-icon name="place" />
</template>
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{text}}</div>
</template>
<template v-slot:append>
<q-icon name="close" @click="text = ''" class="cursor-pointer" />
</template>
<template v-slot:hint>
Field hint
</template>
</q-field>
</div>
</div>
</template>
黑色背景
<template>
<div class="q-pa-md bg-grey-10 text-white">
<div class="q-gutter-y-md column" style="max-width: 300px">
<div>
<q-toggle v-model="readonly" label="Readonly" dark />
<q-toggle v-model="disable" label="Disable" dark />
</div>
<q-field dark :readonly="readonly" :disable="disable">
<template v-slot:prepend>
<q-icon name="event" />
</template>
<template v-slot:control>
<div class="self-center full-width no-outline" :tabindex="tabindex">{{text}}</div>
</template>
</q-field>
<q-field dark filled :readonly="readonly" :disable="disable">
<template v-slot:prepend>
<q-icon name="event" />
</template>
<template v-slot:control>
<div class="self-center full-width no-outline" :tabindex="tabindex">{{text}}</div>
</template>
</q-field>
<q-field dark outlined :readonly="readonly" :disable="disable">
<template v-slot:control>
<div class="self-center full-width no-outline" :tabindex="tabindex">{{text}}</div>
</template>
<template v-slot:append>
<q-avatar>
<img src="https://cdn.quasar.dev/logo-v2/svg/logo-dark.svg">
</q-avatar>
</template>
</q-field>
<q-field dark standout bottom-slots :model-value="text" label="Label" stack-label counter :readonly="readonly" :disable="disable">
<template v-slot:prepend>
<q-icon name="place" />
</template>
<template v-slot:control>
<div class="self-center full-width no-outline" :tabindex="tabindex">{{text}}</div>
</template>
<template v-slot:append>
<q-icon name="close" @click="text = ''" class="cursor-pointer" />
</template>
<template v-slot:hint>
Field hint
</template>
</q-field>
<q-field dark borderless :readonly="readonly" :disable="disable">
<template v-slot:control>
<div class="self-center full-width no-outline" :tabindex="tabindex">{{text}}</div>
</template>
<template v-slot:append>
<q-icon name="search" />
</template>
</q-field>
</div>
</div>
</template>
基础特性
可清除的
作为辅助,您可以使用 clearable
属性,这样用户可以通过附加的图标将数据重置为 null
。下面第二个示例等价于使用 clearable
WARNING
如果使用 clearable
那么您必须使用 v-model
或者监听 @update:model-value
事件并更新其值。
<template>
<div class="q-pa-md">
<div class="q-gutter-y-md column" style="max-width: 300px">
<q-field color="orange" filled v-model="text" label="Label" stack-label clearable>
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">Text is <q>{{text === null ? 'null' : text}}</q></div>
</template>
<template v-if="text === null" v-slot:append>
<q-icon name="short_text" @click.stop="text = 'Some text'" class="cursor-pointer" />
</template>
</q-field>
</div>
</div>
</template>
控件类型
任何您放置在 control
插槽中的内容,都会作为 QFiled 组件的内容展示。我们提供了一些示例:
<template>
<div class="q-pa-md">
<div class="q-gutter-md column" style="max-width: 300px">
<q-field
filled
:hint="`Slider with value ${ slider }`"
:model-value="slider"
@update:model-value="val => (val === null && (slider = 50))"
clearable
>
<template v-slot:control>
<q-slider
:model-value="slider"
@change="val => { slider = val }"
:min="0"
:max="100"
label
label-always
class="q-mt-lg"
/>
</template>
</q-field>
<q-field
filled
:hint="`Range between ${ range.min } and ${ range.max }`"
:model-value="range"
@update:model-value="val => (val === null && (range = { min: 0, max: 100}))"
clearable
>
<template v-slot:control>
<q-range
:model-value="range"
@change="val => { range = val }"
:min="0"
:max="100"
/>
</template>
</q-field>
<q-field
filled
:hint="`Knob with value ${ knob }`"
:model-value="knob"
@update:model-value="val => (val === null && (knob = 50))"
clearable
>
<template v-slot:control>
<div class="full-width">
<q-knob
:model-value="knob"
@change="val => { knob = val }"
:min="0"
:max="100"
size="72px"
:thickness="1"
color="light-blue"
track-color="grey-8"
/>
</div>
</template>
</q-field>
<q-field filled :hint="`Calendar with value ${ date }`" label="Pick a date" stack-label>
<template v-slot:control>
<q-date class="q-mt-sm full-width" minimal v-model="date" />
</template>
</q-field>
<q-field filled :hint="`Time with value ${ time }`" label="Pick a time" stack-label>
<template v-slot:control>
<div class="q-mt-sm full-width">
<q-time v-model="time" />
</div>
</template>
</q-field>
</div>
</div>
</template>
TIP
大部分的表单控件都是可见的,所以如果您在使用 label
属性,那么最好也声明一下stack-label
属性,否则,当 QField 未聚焦时,它可能会与您的控件重叠。
前缀和后缀
<template>
<div class="q-pa-md">
<div class="q-gutter-y-md column" style="max-width: 300px">
<q-field filled :model-value="email" suffix="@gmail.com">
<template v-slot:before>
<q-icon name="mail" />
</template>
<template v-slot:control>
<div class="self-center full-width no-outline text-right" tabindex="0">{{email}}</div>
</template>
</q-field>
<q-field outlined :model-value="number" prefix="$">
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{number}}</div>
</template>
<template v-slot:append>
<q-avatar>
<img src="https://cdn.quasar.dev/logo-v2/svg/logo.svg">
</q-avatar>
</template>
</q-field>
<q-field standout :model-value="email" prefix="Email:" suffix="@gmail.com">
<template v-slot:prepend>
<q-icon name="mail" />
</template>
<template v-slot:control>
<div class="self-center full-width no-outline text-right" tabindex="0">{{email}}</div>
</template>
</q-field>
</div>
</div>
</template>
自定义标签
使用 label
插槽可以自定义标签或使用 QTooltip
添加特殊功能。
TIP
不要忘记设置 label-slot
属性。
如果要与标签(QTooltip)的内容交互,请在插槽中的元素上添加all-pointer-events
CSS 类。
<template>
<div class="q-pa-md">
<div class="q-gutter-y-md column" style="max-width: 300px">
<q-field filled :model-value="email" suffix="@gmail.com" label-slot>
<template v-slot:label>
<div class="row items-center all-pointer-events">
<q-icon class="q-mr-xs" color="deep-orange" size="24px" name="mail" />
Email (hover for more info)
<q-tooltip class="bg-grey-8" anchor="top left" self="bottom left" :offset="[0, 8]">Email address</q-tooltip>
</div>
</template>
<template v-slot:control>
<div class="self-center full-width no-outline text-right" tabindex="0">{{email}}</div>
</template>
</q-field>
<q-field outlined :model-value="number" prefix="$" label-slot>
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{number}}</div>
</template>
<template v-slot:append>
<q-avatar>
<img src="https://cdn.quasar.dev/logo-v2/svg/logo.svg">
</q-avatar>
</template>
<template v-slot:label>
<span class="text-weight-bold text-deep-orange">You</span>
can customize the <span class="q-px-sm bg-deep-orange text-white text-italic rounded-borders">label</span>
</template>
</q-field>
</div>
</div>
</template>
插槽中使用 “submit” 类型的 QBtn
WARNING
当将类型为 “submit” 的 QBtn 放置在 QField、QInput 或 QSelect 的 “before”、“after” 、“prepend” 或 “append” 插槽中时,您还应该在有问题的 QBtn 上添加 @click
事件。该事件应调用提交表单的方法。此类插槽中的所有点击事件均不会传播到其父元素。
加载状态
<template>
<div class="q-pa-md">
<div class="q-gutter-y-md column" style="max-width: 300px">
<q-field
:loading="loadingState"
filled
label="Label"
stack-label
>
<template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{text}}</div>
</template>
</q-field>
<q-toggle v-model="loadingState" label="Loading state" />
</div>
</div>
</template>
验证
内部验证
您可以使用 :rules
属性来对 QField 进行验证。声明一个规则数组或自定义的验证器。自定义的验证器应该是一个函数,当验证成功时返回 true
,验证失败时返回 String
类型的错误信息。
TIP
默认情况下,规则的改变不会触发一次新的验证,直到绑定的数据发生变化。为了在规则改变时触发一次验证,您可以使用 reactive-rules
布尔属性,缺点是会降低性能(所以当您真的需要时在使用它),通过使用计算属性作为规则的值(而不是在 vue 模板中内联指定它们),可以稍微减轻这种情况。
一个规则的格式如下:
value => condition || errorMessage
示例:
value => value < 10 || 'Value should be lower'
您可以通过调用 QField 的 resetValidation()
方法来重置验证。
<template>
<div class="q-pa-md" style="max-width: 400px">
<q-field
ref="fieldRef"
filled
v-model="date"
label="Required Field"
stack-label
:rules="[val => !!val || 'Field is required']"
>
<template v-slot:control>
<q-date class="q-mt-sm full-width" style="width: 300px" minimal v-model="date" />
</template>
</q-field>
<div class="q-mt-sm">
<div class="q-gutter-sm">
<q-btn label="Reset Validation" @click="resetValidation" color="primary"/>
<q-btn label="Reset Date" @click="resetDate" color="primary"/>
</div>
</div>
</div>
</template>
<template>
<div class="q-pa-md" style="max-width: 300px">
<q-field
ref="fieldRef"
filled
:model-value="slider"
label="Maximum 60"
stack-label
:rules="[ val => val <= 60 || 'Please set value to maximum 60' ]"
>
<template v-slot:control>
<q-slider v-model="slider" :min="0" :max="100" label label-always class="q-mt-lg" style="width: 200px" />
</template>
</q-field>
<q-btn class="q-mt-sm" label="Reset Validation" @click="reset" color="primary"/>
</div>
</template>
如果您设置了 lazy-rules
,验证会在第一次失去焦点后才会开始。如果将 lazy-rules
设置为 ondemand
字符串,那么验证只有在手动调用了 QField 组件的 validate() 方法之后才会触发,或者是包裹它的 QForm 触发了提交事件。
<template>
<div class="q-pa-md" style="max-width: 300px">
<q-field
ref="fieldRef"
filled
:model-value="slider"
label="Value must be less than 60"
hint="Validation starts after first blur"
:rules="[
val => val < 60 || 'Please set value to maximum 60',
]"
lazy-rules
>
<template v-slot:control>
<q-slider
v-model="slider"
:min="0"
:max="100"
label
label-always
class="q-mt-lg"
style="width: 200px"
/>
</template>
</q-field>
<q-btn class="q-mt-sm" label="Reset Validation" @click="reset" color="primary"/>
</div>
</template>
异步规则
通过使用 async/await 或直接返回一个 Promise,规则也可以是异步的。
TIP
考虑将异步规则与 debounce
属性相结合,以避免在每次按键时立即调用异步规则,这可能会影响性能。
<template>
<div class="q-pa-md" style="max-width: 350px">
<q-field
ref="fieldRef"
filled
:model-value="slider"
hint="Pick between 10 and 60"
:rules="[ myRule ]"
>
<template v-slot:control>
<q-slider
v-model="slider"
:min="0"
:max="100"
label
label-always
class="q-mt-lg"
style="width: 200px"
/>
</template>
</q-field>
<q-btn class="q-mt-sm" label="Reset Validation" @click="reset" color="primary"/>
</div>
</template>
外部验证
您还可以使用外部验证,并且只传递 error
和 error-message
(启用 bottom-slots
插槽以显示此错误消息)。
TIP
根据您的需求,您可能需要 Vuelidate(我们推荐的方法)或者别的验证库连接到 QField。
<template>
<div class="q-pa-md" style="max-width: 300px">
<q-field
filled
:model-value="slider"
label="Move it above 30"
bottom-slots
hint="Max value is 30"
error-message="Please use a maximum value of 30"
:error="!isValid"
>
<template v-slot:control>
<q-slider v-model="slider" :min="0" :max="100" label label-always class="q-mt-lg" style="width: 200px" />
</template>
</q-field>
</div>
</template>
您还可以为错误消息自定义插槽:
<template>
<div class="q-pa-md" style="max-width: 300px">
<q-field
filled
:model-value="slider"
label="Move it above 30"
bottom-slots
hint="Max value is 30"
:error="!isValid"
>
<template v-slot:control>
<q-slider v-model="slider" :min="0" :max="100" label label-always class="q-mt-lg" style="width: 200px" />
</template>
<template v-slot:error>
Please use a maximum value of 30.
</template>
</q-field>
</div>
</template>
类型定义
export type EmbeddedValidationRule =
| "date"
| "time"
| "fulltime"
| "timeOrFulltime"
| "email"
| "hexColor"
| "hexaColor"
| "hexOrHexaColor"
| "rgbColor"
| "rgbaColor"
| "rgbOrRgbaColor"
| "hexOrRgbColor"
| "hexaOrRgbaColor"
| "anyColor";
type EmbeddedValidationRuleFn = (value: any) => boolean;
export type ValidationRule<T = any> =
| EmbeddedValidationRule
| ((
value: T,
rules: Record<EmbeddedValidationRule, EmbeddedValidationRuleFn>,
) => boolean | string | Promise<boolean | string>);