输入框

QInput 组件用于收集用户输入的文本或数字。它可以像普通的 input 一样使用 v-model。还支持错误验证,并具有多种样式,颜色和类型。

QInput API

QInput API


name
: String
说明
用于指定控件的名称;在处理表单时非常有用;如果未指定,则使用 'for' 属性的值,如果存在的话。
mask
: String
说明
自定义的掩码或预定义的掩码名称
fill-mask
: Boolean | String
说明
用指定的字符(如果值不是字符串,则使用下划线)填充字符串,以填满掩码的长度
reverse-fill-mask
: Boolean
说明
从掩码的右侧填充字符串
unmasked-value
: Boolean
说明
model 数据将被解除掩码(不包含令牌/分隔字符)
error
: Boolean | null
说明
字段是否有验证错误?
rules
: Array
说明
函数/字符串数组;如果是字符串,则必须是内置验证规则之一的名称
reactive-rules
: Boolean
说明
默认情况下,规则的更改不会触发新的验证,直到模型发生变化;如果设置为 true,则规则的更改将触发验证;这会带来性能损失,所以只在真正需要时使用。
lazy-rules
: Boolean | String
说明
如果设置为布尔值 true,则仅在字段第一次失去焦点后才根据 'rules' 检查验证状态;如果设置为 'ondemand',则只有在手动调用组件的 validate() 方法或者当包装器 QForm 提交自身时才会触发。
loading
: Boolean
说明
通过显示一个旋转器来向用户表示进程正在进行中;可以使用 'loading' 插槽自定义旋转器。
clearable
: Boolean
说明
当设置了值(不是 undefined 或 null)时,添加可清除的图标;点击后,model 变为 null
autofocus
: Boolean
说明
在初始组件渲染时聚焦字段
for
: String
说明
用于指定控件的 'id',同时也是包裹它的标签的 'for' 属性;如果没有指定 'name' 属性,则同样用于此属性。

外观设计

WARNING

您只能给 QInput 使用一种主要的外观设计款式(filled, outlined, standout, borderless),不能使用多个,因为它们是互相排斥的。



<template>
  <div class="q-pa-md">
    <div class="q-gutter-md" style="max-width: 300px">
      <q-input v-model="text" label="Standard" />

      <q-input filled v-model="text" label="Filled" />

      <q-input outlined v-model="text" label="Outlined" />

      <q-input standout v-model="text" label="Standout" />

      <q-input standout="bg-teal text-white" v-model="text" label="Custom standout" />

      <q-input borderless v-model="text" label="Borderless" />

      <q-input rounded filled v-model="text" label="Rounded filled" />

      <q-input rounded outlined v-model="text" label="Rounded outlined" />

      <q-input rounded standout v-model="text" label="Rounded standout" />

      <q-input square filled v-model="text" label="Square filled" />

      <q-input square outlined v-model="text" label="Square outlined" />

      <q-input square standout v-model="text" label="Square standout" />
    </div>
  </div>
</template>

着色



<template>
  <div class="q-pa-md">
    <div class="q-gutter-y-md column" style="max-width: 300px">
      <q-input color="purple-12" v-model="text" label="Label">
        <template v-slot:prepend>
          <q-icon name="event" />
        </template>
      </q-input>

      <q-input color="teal" filled v-model="text" label="Label">
        <template v-slot:prepend>
          <q-icon name="event" />
        </template>
      </q-input>

      <q-input color="grey-3" label-color="orange" outlined v-model="text" label="Label">
        <template v-slot:append>
          <q-icon name="event" color="orange" />
        </template>
      </q-input>

      <q-input color="lime-11" bg-color="green" filled v-model="text" label="Label">
        <template v-slot:prepend>
          <q-icon name="event" />
        </template>
      </q-input>

      <q-input color="teal" outlined v-model="text" label="Label">
        <template v-slot:append>
          <q-avatar>
            <img src="https://cdn.quasar.dev/logo-v2/svg/logo.svg">
          </q-avatar>
        </template>
      </q-input>

      <q-input color="orange" standout bottom-slots v-model="text" label="Label" counter clearable>
        <template v-slot:prepend>
          <q-icon name="place" />
        </template>
        <template v-slot:append>
          <q-icon name="favorite" />
        </template>

        <template v-slot:hint>
          Field hint
        </template>
      </q-input>
    </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 QInput" />

      <q-input v-model="text" :dense="dense" />

      <q-input v-model="text" label="Label (stacked)" stack-label :dense="dense" />

      <q-input v-model="text" label="Label" :dense="dense" />

      <q-input v-model="ph" label="Label" placeholder="Placeholder" hint="With placeholder" :dense="dense" />

      <q-input v-model="ph" placeholder="Placeholder" hint="With placeholder" :dense="dense" />

      <q-input v-model="text" :dense="dense">
        <template v-slot:prepend>
          <q-icon name="event" />
        </template>
      </q-input>

      <q-input v-model="text" :dense="dense">
        <template v-slot:append>
          <q-avatar>
            <img src="https://cdn.quasar.dev/logo-v2/svg/logo.svg">
          </q-avatar>
        </template>
      </q-input>

      <q-input bottom-slots v-model="text" label="Label" counter :dense="dense">
        <template v-slot:prepend>
          <q-icon name="place" />
        </template>
        <template v-slot:append>
          <q-icon name="close" @click="text = ''" class="cursor-pointer" />
        </template>

        <template v-slot:hint>
          Field hint
        </template>
      </q-input>

      <q-input bottom-slots v-model="text" label="Label" counter maxlength="12" :dense="dense">
        <template v-slot:before>
          <q-icon name="flight_takeoff" />
        </template>

        <template v-slot:append>
          <q-icon v-if="text !== ''" name="close" @click="text = ''" class="cursor-pointer" />
          <q-icon name="search" />
        </template>

        <template v-slot:hint>
          Field hint
        </template>
      </q-input>

      <q-input bottom-slots v-model="text" label="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:append>
          <q-icon v-if="text !== ''" name="close" @click="text = ''" 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-input>

      <q-input bottom-slots v-model="text" label="Label" counter maxlength="12" :dense="dense">
        <template v-slot:before>
          <q-icon name="event" />
        </template>

        <template v-slot:hint>
          Field hint
        </template>

        <template v-slot:append>
          <q-btn round dense flat icon="add" />
        </template>
      </q-input>

      <q-input v-model="text" hint="Disable" :dense="dense" disable />

      <q-input v-model="text" hint="Readonly" :dense="dense" readonly />

      <q-input v-model="text" hint="Disable and readonly" :dense="dense" disable readonly />
    </div>
  </div>
</template>

Dense QInput

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 QInput" />

      <q-input filled v-model="text" :dense="dense" />

      <q-input filled v-model="text" label="Label (stacked)" stack-label :dense="dense" />

      <q-input filled v-model="text" label="Label" :dense="dense" />

      <q-input filled v-model="ph" label="Label" placeholder="Placeholder" hint="With placeholder" :dense="dense" />

      <q-input filled v-model="ph" placeholder="Placeholder" hint="With placeholder" :dense="dense" />

      <q-input filled square v-model="text" hint="With perfect square borders" :dense="dense" />

      <q-input filled v-model="text" :dense="dense">
        <template v-slot:prepend>
          <q-icon name="event" />
        </template>
      </q-input>

      <q-input filled v-model="text" :dense="dense">
        <template v-slot:append>
          <q-avatar>
            <img src="https://cdn.quasar.dev/logo-v2/svg/logo.svg">
          </q-avatar>
        </template>
      </q-input>

      <q-input filled bottom-slots v-model="text" label="Label" counter :dense="dense">
        <template v-slot:prepend>
          <q-icon name="place" />
        </template>
        <template v-slot:append>
          <q-icon name="close" @click="text = ''" class="cursor-pointer" />
        </template>

        <template v-slot:hint>
          Field hint
        </template>
      </q-input>

      <q-input filled bottom-slots v-model="text" label="Label" counter maxlength="12" :dense="dense">
        <template v-slot:before>
          <q-icon name="flight_takeoff" />
        </template>

        <template v-slot:append>
          <q-icon v-if="text !== ''" name="close" @click="text = ''" class="cursor-pointer" />
          <q-icon name="search" />
        </template>

        <template v-slot:hint>
          Field hint
        </template>
      </q-input>

      <q-input filled bottom-slots v-model="text" label="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:append>
          <q-icon v-if="text !== ''" name="close" @click="text = ''" 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-input>

      <q-input filled bottom-slots v-model="text" label="Label" counter maxlength="12" :dense="dense">
        <template v-slot:before>
          <q-icon name="event" />
        </template>

        <template v-slot:hint>
          Field hint
        </template>

        <template v-slot:append>
          <q-btn round dense flat icon="add" />
        </template>
      </q-input>

      <q-input filled v-model="text" hint="Disable" :dense="dense" disable />

      <q-input filled v-model="text" hint="Readonly" :dense="dense" readonly />

      <q-input filled v-model="text" hint="Disable and readonly" :dense="dense" disable readonly />
    </div>
  </div>
</template>

Dense QInput

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 QInput" />

      <q-input outlined v-model="text" :dense="dense" />

      <q-input outlined v-model="text" label="Label (stacked)" stack-label :dense="dense" />

      <q-input outlined v-model="text" label="Label" :dense="dense" />

      <q-input outlined v-model="ph" label="Label" placeholder="Placeholder" hint="With placeholder" :dense="dense" />

      <q-input outlined v-model="ph" placeholder="Placeholder" hint="With placeholder" :dense="dense" />

      <q-input outlined square v-model="text" hint="With perfect square borders" :dense="dense" />

      <q-input outlined v-model="text" :dense="dense">
        <template v-slot:prepend>
          <q-icon name="event" />
        </template>
      </q-input>

      <q-input outlined v-model="text" :dense="dense">
        <template v-slot:append>
          <q-avatar>
            <img src="https://cdn.quasar.dev/logo-v2/svg/logo.svg">
          </q-avatar>
        </template>
      </q-input>

      <q-input outlined bottom-slots v-model="text" label="Label" counter :dense="dense">
        <template v-slot:prepend>
          <q-icon name="place" />
        </template>
        <template v-slot:append>
          <q-icon name="close" @click="text = ''" class="cursor-pointer" />
        </template>

        <template v-slot:hint>
          Field hint
        </template>
      </q-input>

      <q-input outlined bottom-slots v-model="text" label="Label" counter maxlength="12" :dense="dense">
        <template v-slot:before>
          <q-icon name="flight_takeoff" />
        </template>

        <template v-slot:append>
          <q-icon v-if="text !== ''" name="close" @click="text = ''" class="cursor-pointer" />
          <q-icon name="search" />
        </template>

        <template v-slot:hint>
          Field hint
        </template>
      </q-input>

      <q-input outlined bottom-slots v-model="text" label="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:append>
          <q-icon v-if="text !== ''" name="close" @click="text = ''" 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-input>

      <q-input outlined bottom-slots v-model="text" label="Label" counter maxlength="12" :dense="dense">
        <template v-slot:before>
          <q-icon name="event" />
        </template>

        <template v-slot:hint>
          Field hint
        </template>

        <template v-slot:append>
          <q-btn round dense flat icon="add" />
        </template>
      </q-input>

      <q-input outlined v-model="text" hint="Disable" :dense="dense" disable />

      <q-input outlined v-model="text" hint="Readonly" :dense="dense" readonly />

      <q-input outlined v-model="text" hint="Disable and readonly" :dense="dense" disable readonly />
    </div>
  </div>
</template>

Dense QInput

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-input standout v-model="text" :dense="dense" />

      <q-input standout="bg-teal text-white" v-model="text" label="Custom standout" :dense="dense" />

      <q-input standout v-model="text" label="Label (stacked)" stack-label :dense="dense" />

      <q-input standout v-model="text" label="Label" :dense="dense" />

      <q-input standout v-model="ph" label="Label" placeholder="Placeholder" hint="With placeholder" :dense="dense" />

      <q-input standout v-model="ph" placeholder="Placeholder" hint="With placeholder" :dense="dense" />

      <q-input standout square v-model="text" hint="With perfect square borders" :dense="dense" />

      <q-input standout v-model="text" :dense="dense">
        <template v-slot:prepend>
          <q-icon name="event" />
        </template>
      </q-input>

      <q-input standout v-model="text" :dense="dense">
        <template v-slot:append>
          <q-avatar>
            <img src="https://cdn.quasar.dev/logo-v2/svg/logo.svg">
          </q-avatar>
        </template>
      </q-input>

      <q-input standout bottom-slots v-model="text" label="Label" counter :dense="dense">
        <template v-slot:prepend>
          <q-icon name="place" />
        </template>
        <template v-slot:append>
          <q-icon name="close" @click="text = ''" class="cursor-pointer" />
        </template>

        <template v-slot:hint>
          Field hint
        </template>
      </q-input>

      <q-input standout bottom-slots v-model="text" label="Label" counter maxlength="12" :dense="dense">
        <template v-slot:before>
          <q-icon name="flight_takeoff" />
        </template>

        <template v-slot:append>
          <q-icon v-if="text !== ''" name="close" @click="text = ''" class="cursor-pointer" />
          <q-icon name="search" />
        </template>

        <template v-slot:hint>
          Field hint
        </template>
      </q-input>

      <q-input standout bottom-slots v-model="text" label="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:append>
          <q-icon v-if="text !== ''" name="close" @click="text = ''" 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-input>

      <q-input standout bottom-slots v-model="text" label="Label" counter maxlength="12" :dense="dense">
        <template v-slot:before>
          <q-icon name="event" />
        </template>

        <template v-slot:hint>
          Field hint
        </template>

        <template v-slot:append>
          <q-btn round dense flat icon="add" />
        </template>
      </q-input>

      <q-input standout v-model="text" hint="Disable" :dense="dense" disable />

      <q-input standout v-model="text" hint="Readonly" :dense="dense" readonly />

      <q-input standout v-model="text" hint="Disable and readonly" :dense="dense" disable readonly />
    </div>
  </div>
</template>

Dense QInput

其中一个很合适的的用例就是将 Standout 模式的 QInput 用在 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-input dark dense standout v-model="text" input-class="text-right" class="q-ml-md">
          <template v-slot:append>
            <q-icon v-if="text === ''" name="search" />
            <q-icon v-else name="clear" class="cursor-pointer" @click="text = ''" />
          </template>
        </q-input>
      </q-toolbar>
    </div>
  </div>
</template>

Borderless-无边框

无边框(borderless)设计允许您无缝地将 QInput 集成到其他组件中,而无需 QInput 在其周围绘制边框或更改其背景颜色:



<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-input dark borderless v-model="text" input-class="text-right" class="q-ml-md">
          <template v-slot:append>
            <q-icon v-if="text === ''" name="search" />
            <q-icon v-else name="clear" class="cursor-pointer" @click="text = ''" />
          </template>
        </q-input>
      </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-input rounded filled v-model="text">
        <template v-slot:prepend>
          <q-icon name="event" />
        </template>
      </q-input>

      <q-input rounded outlined v-model="text">
        <template v-slot:append>
          <q-avatar>
            <img src="https://cdn.quasar.dev/logo-v2/svg/logo.svg">
          </q-avatar>
        </template>
      </q-input>

      <q-input rounded standout bottom-slots v-model="text" label="Label" counter>
        <template v-slot:prepend>
          <q-icon name="place" />
        </template>
        <template v-slot:append>
          <q-icon name="close" @click="text = ''" class="cursor-pointer" />
        </template>

        <template v-slot:hint>
          Field hint
        </template>
      </q-input>
    </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-input square filled v-model="text">
        <template v-slot:prepend>
          <q-icon name="event" />
        </template>
      </q-input>

      <q-input square outlined v-model="text">
        <template v-slot:append>
          <q-avatar>
            <img src="https://cdn.quasar.dev/logo-v2/svg/logo.svg">
          </q-avatar>
        </template>
      </q-input>

      <q-input square standout bottom-slots v-model="text" label="Label" counter>
        <template v-slot:prepend>
          <q-icon name="place" />
        </template>
        <template v-slot:append>
          <q-icon name="close" @click="text = ''" class="cursor-pointer" />
        </template>

        <template v-slot:hint>
          Field hint
        </template>
      </q-input>
    </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-input dark v-model="text" :readonly="readonly" :disable="disable">
        <template v-slot:prepend>
          <q-icon name="event" />
        </template>
      </q-input>

      <q-input dark filled v-model="text" :readonly="readonly" :disable="disable">
        <template v-slot:prepend>
          <q-icon name="event" />
          </template>
      </q-input>

      <q-input dark outlined v-model="text" :readonly="readonly" :disable="disable">
        <template v-slot:append>
          <q-avatar>
            <img src="https://cdn.quasar.dev/logo-v2/svg/logo-dark.svg">
          </q-avatar>
        </template>
      </q-input>

      <q-input dark standout bottom-slots v-model="text" label="Label" counter :readonly="readonly" :disable="disable">
        <template v-slot:prepend>
          <q-icon name="place" />
        </template>
        <template v-slot:append>
          <q-icon name="close" @click="text = ''" class="cursor-pointer" />
        </template>

        <template v-slot:hint>
          Field hint
        </template>
      </q-input>

      <q-input dark borderless v-model="text" :readonly="readonly" :disable="disable">
        <template v-slot:append>
          <q-icon name="search" />
        </template>
      </q-input>
    </div>
  </div>
</template>

Readonly
Disable

基础特性

原生属性

所有给 QInput 设置的属性,如果未在 API 卡片中的 props 部分列出,那么它将会被传递给底层的原生标签(inputtextarea)。例如: autocomplete,placeholder。

有关更多原生属性的信息,请参考:

可清除的

作为辅助,您可以使用 clearable 属性,这样用户可以通过附加的图标将数据重置为 null。下面第二个示例等价于使用 clearable

WARNING

如果 v-model 使用了修饰符,例如 .trim,那么 clearable 无法工作,因为 Vue 不会处理 null 值。



<template>
  <div class="q-pa-md">
    <div class="q-gutter-y-md column" style="max-width: 300px">
      <q-input clearable filled color="purple-12" v-model="text" label="Label" />

      <!-- equivalent -->
      <q-input color="orange" filled v-model="text" label="Label">
        <template v-if="text" v-slot:append>
          <q-icon name="cancel" @click.stop="text = null" class="cursor-pointer" />
        </template>
      </q-input>

      <!-- clear-icon -->
      <q-input
        clearable
        clear-icon="close"
        filled
        color="purple-12"
        v-model="text"
        label="Label"
      />
    </div>
  </div>
</template>

输入类型

下面示例中的 QInputs 都使用了 type 属性,以实现与原生等效的 <input type="...">

WARNING

对某些输入类型的支持是浏览器提供的,而不在 Quasar 的核心代码中。



<template>
  <div class="q-pa-md">
    <div class="q-gutter-md row items-start">
      <q-input v-model="password" filled type="password" hint="Password" />

      <q-input v-model="password" filled :type="isPwd ? 'password' : 'text'" hint="Password with toggle">
        <template v-slot:append>
          <q-icon
            :name="isPwd ? 'visibility_off' : 'visibility'"
            class="cursor-pointer"
            @click="isPwd = !isPwd"
          />
        </template>
      </q-input>

      <q-input v-model="email" filled type="email" hint="Email" />

      <q-input v-model="search" filled type="search" hint="Search">
        <template v-slot:append>
          <q-icon name="search" />
        </template>
      </q-input>

      <q-input v-model="tel" filled type="tel" hint="Telephone number" />

      <q-input v-model="url" filled type="url" hint="URL" />

      <q-input v-model="time" filled type="time" hint="Native time" />

      <q-input v-model="date" filled type="date" hint="Native date" />
    </div>
  </div>
</template>

TIP

某些输入类型(如 datetime)总是呈现某些控件,因此如果使用 label,则可能需要将其与 stack-label 一起设置,否则标签将与原生浏览器控件重叠。

输入数字类型

您可以使用 v-model.number (注意 number 修饰符)以及 type="number" 属性:



<template>
  <div class="q-pa-md">
    <q-input
      v-model.number="model"
      type="number"
      filled
      style="max-width: 200px"
    />
  </div>
</template>

输入文件类型

替代选择

推荐您使用 QFile,甚至是 QUploader 来收集文件,而不是使用 type="file" 的 QInput。但是,如果您仍希望使用 QInput,请阅读以下警告

WARNING

当设置 QInput 的 type="file"时,请勿使用 v-model。浏览器安全策略不允许将值设置为此类输入。因此,您只能读取它(附加一个 @update:model-value 事件),而不能写入它。



<template>
  <div class="q-pa-md">
    <div class="q-gutter-md row items-start">
      <!--
        Due to browser security policy,
        we can only read the value, but not
        write to it, so we only have an @update:model-value listener
      -->

      <q-input
        @update:model-value="val => { file = val[0] }"
        filled
        type="file"
        hint="Native file"
      />

      <q-input
        @update:model-value="val => { files = val }"
        multiple
        filled
        type="file"
        hint="Native file (multiple)"
      />
    </div>
  </div>
</template>

文本域



<template>
  <div class="q-pa-md" style="max-width: 300px">
    <q-input
      v-model="text"
      filled
      type="textarea"
    />
  </div>
</template>

当您需要 QInput 与其内容一起增长时,请使用如下示例中的 autogrow 属性:



<template>
  <div class="q-pa-md" style="max-width: 300px">
    <q-input
      v-model="text"
      filled
      autogrow
    />
  </div>
</template>

前缀和后缀



<template>
  <div class="q-pa-md">
    <div class="q-gutter-y-md column" style="max-width: 300px">
      <q-input filled v-model="email" type="email" suffix="@gmail.com">
        <template v-slot:before>
          <q-icon name="mail" />
        </template>
      </q-input>

      <q-input outlined v-model="number" type="number" prefix="$">
        <template v-slot:append>
          <q-avatar>
            <img src="https://cdn.quasar.dev/logo-v2/svg/logo.svg">
          </q-avatar>
        </template>
      </q-input>

      <q-input standout v-model="email" type="email" prefix="Email:" suffix="@gmail.com">
        <template v-slot:prepend>
          <q-icon name="mail" />
        </template>
      </q-input>
    </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-input filled v-model="email" suffix="@gmail.com" input-class="text-right" label-slot clearable>
        <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>
      </q-input>

      <q-input outlined v-model="number" prefix="$" label-slot clearable>
        <template v-slot:prepend>
          <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-input>
    </div>
  </div>
</template>

阴影文本



<template>
  <div class="q-pa-md">
    <div class="q-gutter-y-md column" style="max-width: 300px">
      <q-input
        v-model="inputModel"
        filled
        clearable
        color="purple-12"
        label="Input with shadow text"
        hint="Press TAB to autocomplete suggested value or ESC to cancel suggestion"
        :shadow-text="inputShadowText"
        @keydown="processInputFill"
        @focus="processInputFill"
      />

      <q-input
        v-model="textareaModel"
        filled
        clearable
        autogrow
        color="green-8"
        label="Autogrow textarea with shadow text"
        hint="Press TAB to autocomplete suggested value or ESC to cancel suggestion"
        :shadow-text="textareaShadowText"
        @keydown="processTextareaFill"
        @focus="processTextareaFill"
      />

      <q-input
        v-model="textareaModel"
        filled
        clearable
        type="textarea"
        color="red-12"
        label="Textarea with shadow text"
        hint="Press TAB to autocomplete suggested value or ESC to cancel suggestion"
        :shadow-text="textareaShadowText"
        @keydown="processTextareaFill"
        @focus="processTextareaFill"
      />
    </div>
  </div>
</template>

插槽中使用 “submit” 类型的 QBtn

WARNING

当将类型为 “submit” 的 QBtn 放置在 QField、QInput 或 QSelect 的 “before”、“after” 、“prepend” 或 “append” 插槽中时,您还应该在有问题的 QBtn 上添加 @click 事件。该事件应调用提交表单的方法。此类插槽中的所有点击事件均不会传播到其父元素。

防抖模式

当您监听被绑定的数据的变化并对其进行昂贵的操作时,防抖的作用就体现出来了。我们一般希望先让用户完成整个输入之后再触发数据更新,而不是在每次按键时都更新数据。



<template>
  <div class="q-pa-md" style="max-width: 350px">
    <div class="q-gutter-md">
      <div>
        <q-badge color="teal">Model: "{{ search }}"</q-badge>
      </div>

      <q-input
        v-model="search"
        debounce="500"
        filled
        placeholder="Search"
        hint="Debouncing 500ms"
      >
        <template v-slot:append>
          <q-icon name="search" />
        </template>
      </q-input>

      <q-input
        v-model="search"
        debounce="1000"
        filled
        placeholder="Search"
        hint="Debouncing 1000ms"
      >
        <template v-slot:append>
          <q-icon name="search" />
        </template>
      </q-input>
    </div>
  </div>
</template>

Model: ""

加载状态



<template>
  <div class="q-pa-md">
    <div class="q-gutter-y-md column" style="max-width: 300px">
      <q-input
        :loading="loadingState"
        filled
        v-model="text"
        label="Label"
      />
      <q-toggle v-model="loadingState" label="Loading state" />
    </div>
  </div>
</template>

Loading state

掩码

您可以通过 mask 属性强制/辅助用户输入一个特定格式的文本

WARNING

掩码只在 type 为 ‘text’(默认)、 ‘search’、 ‘url’、 ‘tel’、 或 ‘password’ 其中之一时才能使用。‘password’.

下面是掩码符号:

符号说明
#数字
S字母,a 到 z,不区分大小写
N字母数字,字母不区分大小写
A字母,转换为大写
a字母,转换为小写
X字母数字,字母转换为大写
x字母数字,字母转换为小写

这里有一组可用在 QInput mask 属性中的工具。 为了方便起见,可以直接使用它们(例如:“phone”、“card”)或写出您的自定义需求的字符串。



<template>
  <div class="q-pa-md" style="max-width: 300px">
    <div class="q-gutter-md">
      <q-input
        filled
        v-model="id"
        label="Special ID"
        mask="###/##"
        hint="Mask: ###/##"
      />

      <q-input
        filled
        v-model="phone"
        label="Phone"
        mask="(###) ### - ####"
        hint="Mask: (###) ### - ####"
      />

      <q-input
        filled
        v-model="serialNumber"
        label="Serial number"
        mask="AAAA - #### - #### - SSS"
        hint="Mask: AAAA - #### - #### - SSS"
      />
    </div>
  </div>
</template>



<template>
  <div class="q-pa-md" style="max-width: 300px">
    <div class="q-gutter-md">
      <q-input
        filled
        v-model="id"
        label="Special ID"
        mask="###/##"
        fill-mask
        hint="Mask: ###/##"
      />

      <q-input
        filled
        v-model="phone"
        label="Phone"
        mask="(###) ### - ####"
        fill-mask
        hint="Mask: (###) ### - ####"
      />

      <q-input
        filled
        v-model="card"
        label="Card"
        mask="#### #### #### ####"
        fill-mask="#"
        hint="Mask: #### #### #### ####, FillMask: #"
      />
    </div>
  </div>
</template>

如果要强制用户输入特定格式,但希望数据中又只包含原始值(不包含掩码符号和分隔符),则 unmasked-value 很有用:



<template>
  <div class="q-pa-md" style="max-width: 300px">
    <div class="q-gutter-md">
      <q-badge color="secondary">Id model: "{{ id }}"</q-badge>
      <q-input
        filled
        v-model="id"
        label="Special Id"
        mask="###/##"
        unmasked-value
        hint="Mask: ###/##"
      />

      <q-badge color="secondary">Phone model: "{{ phone }}"</q-badge>
      <q-input
        filled
        v-model="phone"
        label="Phone"
        mask="(###) ### - ####"
        unmasked-value
        hint="Mask: (###) ### - ####"
      />

      <q-badge color="secondary">Card model: "{{ card }}"</q-badge>
      <q-input
        filled
        v-model="card"
        label="Card"
        mask="#### - #### - #### - ####"
        fill-mask="#"
        unmasked-value
        hint="Mask: #### - #### - #### - ####, FillMask: #"
      />
    </div>
  </div>
</template>

Id model: ""
Phone model: ""
Card model: ""

如果要强制用户从末端填充掩码并允许非固定长度的输入,则 reverse-fill-mask 很有用:



<template>
  <div class="q-pa-md" style="max-width: 300px">
    <div class="q-gutter-md">
      <q-input
        filled
        v-model="price"
        label="Price with 2 decimals"
        mask="#.##"
        fill-mask="0"
        reverse-fill-mask
        hint="Mask: #.##"
        input-class="text-right"
      />
    </div>
  </div>
</template>

使用第三方掩码处理器

通过对 QInput 进行一些小调整,您可以轻松使用任何第三方掩码处理器。

从这样的 QInput 开始:

<q-input
  filled
  v-model="price"
  label="Price with 2 decimals"
  mask="#.##"
  fill-mask="#"
  reverse-fill-mask
  hint="Mask: #.00"
  input-class="text-right"
/>

您可以使用 v-money 指令:

<q-field
  filled
  v-model="price"
  label="Price with v-money directive"
  hint="Mask: $ #,###.00 #"
>
  <template v-slot:control="{ id, floatingLabel, modelValue, emitValue }">
    <input :id="id" class="q-field__input text-right" :value="modelValue" @change="e => emitValue(e.target.value)" v-money="moneyFormatForDirective" v-show="floatingLabel">
  </template>
</q-field>
moneyFormatForDirective: {
  decimal: '.',
  thousands: ',',
  prefix: '$ ',
  suffix: ' #',
  precision: 2,
  masked: false /* 不能与指令一起工作 */
}

或者您可以使用 money 组件:

<q-field
  filled
  v-model="price"
  label="Price with v-money component"
  hint="Mask: $ #,###.00 #"
>
  <template v-slot:control="{ id, floatingLabel, modelValue, emitValue }">
    <money :id="id" class="q-field__input text-right" :model-value="modelValue" @update:model-value="emitValue" v-bind="moneyFormatForComponent" v-show="floatingLabel" />
  </template>
</q-field>
moneyFormatForComponent: {
  decimal: '.',
  thousands: ',',
  prefix: '$ ',
  suffix: ' #',
  precision: 2,
  masked: true
}

验证

内部验证

您可以使用 :rules 属性来对 QInput 进行验证。声明一个规则数组或自定义的验证器。自定义的验证器应该是一个函数,当验证成功时返回 true,验证失败时返回 String 类型的错误信息。

TIP

默认情况下,规则的改变不会触发一次新的验证,直到绑定的数据发生变化。为了在规则改变时触发一次验证,您可以使用 reactive-rules 布尔属性,缺点是会降低性能(所以当您真的需要时在使用它),通过使用计算属性作为规则的值(而不是在 vue 模板中内联指定它们),可以稍微减轻这种情况。

一个规则的格式如下:

value => condition || errorMessage

示例:

value => value.includes('Hello') || 'Field must contain word Hello'

您可以通过调用 QInput 的 resetValidation() 方法来重置验证。

这里有一组可用在 QInput rules 属性中的工具。 为了方便起见,可以直接使用它们(例如: “date”, “time”, “hexColor”, “rgbOrRgbaColor”, “anyColor”)或写出您的自定义需求的字符串。



<template>
  <div class="q-pa-md" style="max-width: 300px">
    <q-input
      ref="inputRef"
      filled
      v-model="model"
      label="Required Field"
      :rules="[val => !!val || 'Field is required']"
    />

    <q-btn class="q-mt-sm" label="Reset Validation" @click="reset" color="primary"/>
  </div>
</template>



<template>
  <div class="q-pa-md" style="max-width: 300px">
    <q-input
      ref="inputRef"
      filled
      v-model="model"
      label="Maximum 3 characters"
      :rules="[ val => val.length <= 3 || 'Please use maximum 3 characters']"
    />

    <q-btn class="q-mt-sm" label="Reset Validation" @click="reset" color="primary"/>
  </div>
</template>

如果您设置了 lazy-rules,验证会在第一次失去焦点后才会开始。如果将 lazy-rules 设置为 ondemand 字符串,那么验证只有在手动调用了 QInput 组件的 validate() 方法之后才会触发,或者是包裹它的 QForm 触发了提交事件。



<template>
  <div class="q-pa-md" style="max-width: 300px">
    <q-input
      ref="inputRef"
      filled
      v-model="model"
      label="Required field with length < 2"
      hint="Validation starts after first blur"
      counter
      :rules="[
          val => !!val || '* Required',
          val => val.length < 2 || 'Please use maximum 1 character',
        ]"
      lazy-rules
    />

    <q-btn class="q-mt-sm" label="Reset Validation" @click="reset" color="primary"/>
  </div>
</template>



<template>
  <div class="q-pa-md" style="max-width: 300px">
    <form @submit.prevent.stop="onSubmit" @reset.prevent.stop="onReset" class="q-gutter-md">
      <q-input
        ref="nameRef"
        filled
        v-model="name"
        label="Your name *"
        hint="Name and surname"
        lazy-rules
        :rules="nameRules"
      />

      <q-input
        ref="ageRef"
        filled
        type="number"
        v-model="age"
        label="Your age *"
        lazy-rules
        :rules="ageRules"
      />

      <q-toggle v-model="accept" label="I accept the license and terms" />

      <div>
        <q-btn label="Submit" type="submit" color="primary" />
        <q-btn label="Reset" type="reset" color="primary" flat class="q-ml-sm" />
      </div>
    </form>
  </div>
</template>

I accept the license and terms

异步规则

通过使用 async/await 或直接返回一个 Promise,规则也可以是异步的。

TIP

考虑将异步规则与 debounce 属性相结合,以避免在每次按键时立即调用异步规则,这可能会影响性能。



<template>
  <div class="q-pa-md" style="max-width: 300px">
    <q-input
      ref="inputRef"
      filled
      v-model="model"
      label="Required Field *"
      :rules="[ myRule ]"
    />

    <q-btn class="q-mt-sm" label="Reset Validation" @click="reset" color="primary"/>
  </div>
</template>

外部验证

您还可以使用外部验证,并且只传递 errorerror-message(启用 bottom-slots 插槽以显示此错误消息)。

TIP

根据您的需求,您可能需要 Vuelidate(我们推荐的方法)或者别的验证库连接到 QInput。



<template>
  <div class="q-pa-md" style="max-width: 300px">
    <q-input
      filled
      v-model="model"
      label="Type here"
      bottom-slots
      hint="Max 3 characters"
      error-message="Please use maximum 3 characters"
      :error="!isValid"
    />
  </div>
</template>

您还可以为错误消息自定义插槽:



<template>
  <div class="q-pa-md" style="max-width: 300px">
    <q-input
      filled
      v-model="model"
      label="Type here"
      bottom-slots
      :error="!isValid"
      hint="Max 3 characters"
    >
      <template v-slot:error>
        Please use maximum 3 characters.
      </template>
    </q-input>
  </div>
</template>

原生表单提交

当处理一个带有 actionmethod 的原生表单时(如:使用 Quasar 和 ASP.NET 控制器时),您需要为 QInput 声明 name 属性,否则表单数据中不会包含它:



<template>
  <div class="q-pa-md">
    <q-form @submit="onSubmit" class="q-gutter-md">
      <q-input
        name="name"
        v-model="name"
        color="primary"
        label="Full name"
        filled
        clearable
      />

      <div>
        <q-btn label="Submit" type="submit" color="primary"/>
      </div>
    </q-form>

    <q-card v-if="submitResult.length > 0" flat bordered class="q-mt-md bg-grey-2">
      <q-card-section>Submitted form contains the following formData (key = value):</q-card-section>
      <q-separator />
      <q-card-section class="row q-gutter-sm items-center">
        <div
          v-for="(item, index) in submitResult"
          :key="index"
          class="q-px-sm q-py-xs bg-grey-8 text-white rounded-borders text-center text-no-wrap"
        >{{ item.name }} = {{ item.value }}</div>
      </q-card-section>
    </q-card>
  </div>
</template>

类型定义

type QInputType = NonNullable<QInputProps["type"]>;

type WithKnownType<
  TElement extends HTMLInputElement | HTMLTextAreaElement,
  TType extends QInputType,
> = Omit<TElement, "type"> & { type: TType };

/**
 * @example
 * ```ts
 * QInputNativeElement                      
 * QInputNativeElement<"textarea">          
 * QInputNativeElement<"text">              
 * QInputNativeElement<"text" | "number">   
 * QInputNativeElement<"text" | "textarea"> 
 * ```
 */
export type QInputNativeElement<T extends QInputType = QInputType> =
  T extends "textarea"
    ? WithKnownType<HTMLTextAreaElement, "textarea">
    : Omit<WithKnownType<HTMLInputElement, T>, "files"> & {
        files: T extends "file" ? FileList : null;
      };