文本框
文本框组件用于收集用户提供的信息。
用例
具有占位符 和/或 标签的简单文本字段。
template
<template>
<v-form>
<v-container>
<v-row>
<v-col cols="12" sm="6" md="3">
<v-text-field
label="Regular"
></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="3">
<v-text-field
label="Regular"
placeholder="Placeholder"
></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="3">
<v-text-field
label="Solo"
solo
></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="3">
<v-text-field
label="Solo"
placeholder="Placeholder"
solo
></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="3">
<v-text-field
label="Filled"
filled
></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="3">
<v-text-field
label="Filled"
placeholder="Placeholder"
filled
></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="3">
<v-text-field
label="Outlined"
outlined
></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="3">
<v-text-field
label="Outlined"
placeholder="Placeholder"
outlined
></v-text-field>
</v-col>
</v-row>
</v-container>
</v-form>
</template>
API
从下面选择您想要的组件,并查看可用的属性、插槽、事件和函数。
实战场
template script
<template>
<v-container fluid>
<v-row>
<v-col
cols="12"
sm="6"
>
<v-text-field
v-model="label"
label="Label"
></v-text-field>
<v-text-field
v-model="hint"
label="Hint"
></v-text-field>
<v-text-field
v-model="placeholder"
label="Placeholder"
></v-text-field>
</v-col>
<v-col cols="12"></v-col>
<v-col
cols="12"
md="6"
>
<v-switch
v-model="shaped"
class="ma-1"
label="Shaped (requires Filled, Outlined or Solo)"
:disabled="!outlined && !filled && !solo"
></v-switch>
<v-switch
v-model="outlined"
class="ma-1"
label="Outlined"
></v-switch>
<v-switch
v-model="rounded"
class="ma-1"
label="Rounded (requires Filled, Outlined or Solo)"
:disabled="!filled && !outlined && !solo"
></v-switch>
<v-switch
v-model="solo"
class="ma-1"
label="Solo"
:disabled="filled"
></v-switch>
<v-switch
v-model="singleLine"
class="ma-1"
label="Single-line"
></v-switch>
<v-switch
v-model="filled"
class="ma-1"
label="Filled"
:disabled="outlined || solo"
></v-switch>
<v-switch
v-model="clearable"
class="ma-1"
label="Clearable"
></v-switch>
<v-switch
v-model="persistentHint"
class="ma-1"
label="Persistent Hint"
></v-switch>
<v-switch
v-model="loading"
class="ma-1"
label="Loading"
></v-switch>
<v-switch
v-model="flat"
class="ma-1"
label="Flat (requires Solo)"
:disabled="!solo"
></v-switch>
<v-switch
v-model="dense"
class="ma-1"
label="Dense"
></v-switch>
<v-row>
<v-switch
v-model="counterEn"
class="ma-0 mr-2 ml-1"
label="Counter"
></v-switch>
<v-slider
v-model="counter"
:disabled="!counterEn"
></v-slider>
</v-row>
</v-col>
<v-col
cols="12"
md="6"
>
<v-sheet
elevation="12"
class="pa-12"
>
<v-text-field
v-model="model"
:label="label"
:hint="hint"
:placeholder="placeholder"
:shaped="shaped"
:outlined="outlined"
:rounded="rounded"
:solo="solo"
:single-line="singleLine"
:filled="filled"
:clearable="clearable"
:persistent-hint="persistentHint"
:loading="loading"
:flat="flat"
:counter="counterEn ? counter : false"
:dense="dense"
></v-text-field>
<div class="mt-12 text-center">
Value: {{ model }}
</div>
</v-sheet>
</v-col>
</v-row>
</v-container>
</template>
<script>
export default {
data: () => ({
model: 'I\'m a text field',
label: 'Hey!',
hint: 'Customize me!',
placeholder: '',
shaped: false,
outlined: false,
rounded: false,
solo: false,
singleLine: false,
filled: false,
clearable: false,
persistentHint: false,
loading: false,
flat: false,
counterEn: false,
counter: 0,
dense: false,
}),
}
</script>
示例
下面是一些简单到复杂的例子。
单行
单行文本框的标签不会浮动到焦点或数据之上。
template
<template>
<v-form>
<v-container>
<v-row>
<v-col cols="12" sm="6">
<v-text-field
label="Regular"
single-line
></v-text-field>
</v-col>
<v-col cols="12" sm="6">
<v-text-field
label="Solo"
single-line
solo
></v-text-field>
</v-col>
<v-col cols="12" sm="6">
<v-text-field
label="Filled"
single-line
filled
></v-text-field>
</v-col>
<v-col cols="12" sm="6">
<v-text-field
label="Outlined"
single-line
outlined
></v-text-field>
</v-col>
</v-row>
</v-container>
</v-form>
</template>
形状
shaped
文本框如果被 outlined
则显示为圆角,如果被 filled
,则为更高的 border-radius
。
template script
<template>
<v-form>
<v-container>
<v-row>
<v-col cols="12" sm="6">
<v-text-field
v-model="first"
label="First Name"
outlined
shaped
></v-text-field>
</v-col>
<v-col cols="12" sm="6">
<v-text-field
v-model="last"
label="Last Name"
filled
shaped
></v-text-field>
</v-col>
</v-row>
</v-container>
</v-form>
</template>
<script>
export default {
data: () => ({
first: 'John',
last: 'Doe',
}),
}
</script>
禁用且只读
文本框可以是 disabled
或 readonly
。
template
<template>
<v-form>
<v-container>
<v-row>
<v-col cols="12" sm="6">
<v-text-field
value="John Doe"
label="Regular"
disabled
></v-text-field>
</v-col>
<v-col cols="12" sm="6">
<v-text-field
value="John Doe"
label="Regular"
readonly
></v-text-field>
</v-col>
<v-col cols="12" sm="6">
<v-text-field
value="John Doe"
label="Solo"
solo
disabled
></v-text-field>
</v-col>
<v-col cols="12" sm="6">
<v-text-field
value="John Doe"
label="Solo"
solo
readonly
></v-text-field>
</v-col>
<v-col cols="12" sm="6">
<v-text-field
value="John Doe"
label="Filled"
filled
disabled
></v-text-field>
</v-col>
<v-col cols="12" sm="6">
<v-text-field
value="John Doe"
label="Filled"
filled
readonly
></v-text-field>
</v-col>
<v-col cols="12" sm="6">
<v-text-field
value="John Doe"
label="Outlined"
outlined
disabled
></v-text-field>
</v-col>
<v-col cols="12" sm="6">
<v-text-field
value="John Doe"
label="Outlined"
outlined
readonly
></v-text-field>
</v-col>
</v-row>
</v-container>
</v-form>
</template>
密集
您可以使用 dense
属性降低文本字段的高度。
template
<template>
<v-form>
<v-container>
<v-row>
<v-col cols="12" sm="6" md="4">
<v-text-field
dense
label="Regular"
></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="4">
<v-text-field
label="Filled"
filled
dense
></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="4">
<v-text-field
label="Filled"
placeholder="Dense & Rounded"
filled
rounded
dense
></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="4">
<v-text-field
label="Solo"
solo
dense
></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="4">
<v-text-field
label="Outlined"
outlined
dense
></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="4">
<v-text-field
label="Outlined"
placeholder="Placeholder"
outlined
dense
></v-text-field>
</v-col>
</v-row>
</v-container>
</v-form>
</template>
图标
您可以使用 prepend-icon
, append-icon
和 append-outer-icon
属性添加图标到文本字段
template
<template>
<v-form>
<v-container>
<v-row>
<v-col cols="12" sm="6">
<v-text-field
label="Prepend"
prepend-icon="place"
></v-text-field>
<v-text-field
label="Prepend inner"
prepend-inner-icon="place"
></v-text-field>
<v-text-field
label="Append"
append-icon="place"
></v-text-field>
<v-text-field
label="Append outer"
append-outer-icon="place"
></v-text-field>
</v-col>
<v-col cols="12" sm="6">
<v-text-field
solo
label="Prepend"
prepend-icon="place"
></v-text-field>
<v-text-field
solo
label="Prepend inner"
prepend-inner-icon="place"
></v-text-field>
<v-text-field
solo
label="Append"
append-icon="place"
></v-text-field>
<v-text-field
solo
label="Append outer"
append-outer-icon="place"
></v-text-field>
</v-col>
<v-col cols="12" sm="6">
<v-text-field
filled
label="Prepend"
prepend-icon="place"
></v-text-field>
<v-text-field
filled
label="Prepend inner"
prepend-inner-icon="place"
></v-text-field>
<v-text-field
filled
label="Append"
append-icon="place"
></v-text-field>
<v-text-field
filled
label="Append outer"
append-outer-icon="place"
></v-text-field>
</v-col>
<v-col cols="12" sm="6">
<v-text-field
outlined
label="Prepend"
prepend-icon="place"
></v-text-field>
<v-text-field
outlined
label="Prepend inner"
prepend-inner-icon="place"
></v-text-field>
<v-text-field
outlined
label="Append"
append-icon="place"
></v-text-field>
<v-text-field
outlined
label="Append outer"
append-outer-icon="place"
></v-text-field>
</v-col>
</v-row>
</v-container>
</v-form>
</template>
可清除
当处于 clearable
时,您可以使用 clear-icon
自定义清除图标。
template script
<template>
<v-form>
<v-container>
<v-row>
<v-col cols="12" sm="6">
<v-text-field
v-model="message1"
label="Regular"
clearable
></v-text-field>
</v-col>
<v-col cols="12" sm="6">
<v-text-field
v-model="message2"
solo
label="Solo"
clearable
></v-text-field>
</v-col>
<v-col cols="12" sm="6">
<v-text-field
v-model="message3"
filled
label="Filled"
clearable
></v-text-field>
</v-col>
<v-col cols="12" sm="6">
<v-text-field
v-model="message4"
label="Outlined"
outlined
clearable
></v-text-field>
</v-col>
</v-row>
</v-container>
</v-form>
</template>
<script>
export default {
data () {
return {
message1: 'Hey!',
message2: 'Hey!',
message3: 'Hey!',
message4: 'Hey!',
}
},
}
</script>
字符计数器
使用 counter
属性来通知用户字符限制。 计数器本身不会执行任何验证。 您需要将其与内部验证系统或第三方库配对。 您可以在常规,方框或轮廓文本字段中使用它。
template script
<template>
<v-form>
<v-container>
<v-row>
<v-col cols="12" sm="6">
<v-text-field
v-model="title"
:rules="rules"
counter="25"
hint="This field uses counter prop"
label="Regular"
></v-text-field>
</v-col>
<v-col cols="12" sm="6">
<v-text-field
v-model="description"
:rules="rules"
counter
maxlength="25"
hint="This field uses maxlength attribute"
label="Limit exceeded"
></v-text-field>
</v-col>
<v-col cols="12" sm="6">
<v-text-field
v-model="title"
:rules="rules"
counter="25"
filled
label="Filled"
></v-text-field>
</v-col>
<v-col cols="12" sm="6">
<v-text-field
v-model="title"
:rules="rules"
counter="25"
label="Outlined"
outlined
></v-text-field>
</v-col>
</v-row>
</v-container>
</v-form>
</template>
<script>
export default {
data () {
return {
title: 'Preliminary report',
description: 'California is a state in the western United States',
rules: [v => v.length <= 25 || 'Max 25 characters'],
}
},
}
</script>
自动隐藏详细信息
当 hide-details
设置为 auto
时,只有在有消息(提示、错误消息、计数器值等)要显示时,才会显示消息。
template script
<template>
<div>
<v-text-field label="Main input" :rules="rules" hide-details="auto"></v-text-field>
<v-text-field label="Another input"></v-text-field>
</div>
</template>
<script>
export default {
data: () => ({
rules: [
value => !!value || 'Required.',
value => (value && value.length >= 3) || 'Min 3 characters',
],
}),
}
</script>
密码输入
密码输入可以用附加图标以及回调一起控制密码的可见性。
template script
<template>
<v-form>
<v-container fluid>
<v-row>
<v-col cols="12" sm="6">
<v-text-field
v-model="password"
:append-icon="show1 ? 'mdi-eye' : 'mdi-eye-off'"
:rules="[rules.required, rules.min]"
:type="show1 ? 'text' : 'password'"
name="input-10-1"
label="Normal with hint text"
hint="At least 8 characters"
counter
@click:append="show1 = !show1"
></v-text-field>
</v-col>
<v-col cols="12" sm="6">
<v-text-field
:append-icon="show2 ? 'mdi-eye' : 'mdi-eye-off'"
:rules="[rules.required, rules.min]"
:type="show2 ? 'text' : 'password'"
name="input-10-2"
label="Visible"
hint="At least 8 characters"
value="wqfasds"
class="input-group--focused"
@click:append="show2 = !show2"
></v-text-field>
</v-col>
<v-col cols="12" sm="6">
<v-text-field
:append-icon="show3 ? 'mdi-eye' : 'mdi-eye-off'"
:rules="[rules.required, rules.min]"
:type="show3 ? 'text' : 'password'"
name="input-10-2"
label="Not visible"
hint="At least 8 characters"
value="wqfasds"
class="input-group--focused"
@click:append="show3 = !show3"
></v-text-field>
</v-col>
<v-col cols="12" sm="6">
<v-text-field
:append-icon="show4 ? 'mdi-eye' : 'mdi-eye-off'"
:rules="[rules.required, rules.emailMatch]"
:type="show4 ? 'text' : 'password'"
name="input-10-2"
label="Error"
hint="At least 8 characters"
value="Pa"
error
@click:append="show4 = !show4"
></v-text-field>
</v-col>
</v-row>
</v-container>
</v-form>
</template>
<script>
export default {
data () {
return {
show1: false,
show2: true,
show3: false,
show4: false,
password: 'Password',
rules: {
required: value => !!value || 'Required.',
min: v => v.length >= 8 || 'Min 8 characters',
emailMatch: () => ('The email and password you entered don\'t match'),
},
}
},
}
</script>
盒子样式
文本框可以使用替代的样式设计,但是这种模式下不支持附加或者前置图标属性。
template script
<template>
<v-form>
<v-container>
<v-row>
<v-col cols="12" sm="6">
<v-text-field
v-model="first"
label="First Name"
filled
></v-text-field>
</v-col>
<v-col cols="12" sm="6">
<v-text-field
v-model="last"
label="Last Name"
filled
></v-text-field>
</v-col>
</v-row>
</v-container>
</v-form>
</template>
<script>
export default {
data: () => ({
first: 'John',
last: 'Doe',
}),
}
</script>
单独样式
文本字段可以与其他单独设计一起使用。
template script
<template>
<v-form>
<v-container>
<v-row>
<v-col cols="12" sm="6">
<v-text-field
v-model="first"
label="First Name"
solo
></v-text-field>
</v-col>
<v-col cols="12" sm="6">
<v-text-field
v-model="last"
label="Last Name"
solo-inverted
></v-text-field>
</v-col>
</v-row>
</v-container>
</v-form>
</template>
<script>
export default {
data: () => ({
first: 'John',
last: 'Doe',
}),
}
</script>
Alpha Theme
Complete theme experience including enhanced Vue CLI, full documentation, 5 custom components and much more!
ads by Vuetify
](https://store.vuetifyjs.com/product/alpha-theme?ref=vuetifyjs.com)
轮廓样式
文本字段可以与其他轮廓设计一起使用。
template script
<template>
<v-form>
<v-container>
<v-row>
<v-col cols="12" sm="6">
<v-text-field
v-model="first"
label="First Name"
outlined
></v-text-field>
</v-col>
<v-col cols="12" sm="6">
<v-text-field
v-model="last"
label="Last Name"
outlined
></v-text-field>
</v-col>
</v-row>
</v-container>
</v-form>
</template>
<script>
export default {
data: () => ({
first: 'John',
last: 'Doe',
}),
}
</script>
自定义颜色
你可以将文本框的颜色更改为 Material design 调色板中的任何颜色。下面是带验证的自定义表单的示例实现。
template script
<template>
<v-card flat>
<v-snackbar
v-model="snackbar"
absolute
top
right
color="success"
>
<span>Registration successful!</span>
<v-icon dark>mdi-checkbox-marked-circle</v-icon>
</v-snackbar>
<v-form ref="form" @submit.prevent="submit">
<v-container fluid>
<v-row>
<v-col cols="12" sm="6">
<v-text-field
v-model="form.first"
:rules="rules.name"
color="purple darken-2"
label="First name"
required
></v-text-field>
</v-col>
<v-col cols="12" sm="6">
<v-text-field
v-model="form.last"
:rules="rules.name"
color="blue darken-2"
label="Last name"
required
></v-text-field>
</v-col>
<v-col cols="12">
<v-textarea
v-model="form.bio"
color="teal"
>
<template v-slot:label>
<div>
Bio <small>(optional)</small>
</div>
</template>
</v-textarea>
</v-col>
<v-col cols="12" sm="6">
<v-select
v-model="form.favoriteAnimal"
:items="animals"
:rules="rules.animal"
color="pink"
label="Favorite animal"
required
></v-select>
</v-col>
<v-col cols="12" sm="6">
<v-slider
v-model="form.age"
:rules="rules.age"
color="orange"
label="Age"
hint="Be honest"
min="1"
max="100"
thumb-label
></v-slider>
</v-col>
<v-col cols="12">
<v-checkbox
v-model="form.terms"
color="green"
>
<template v-slot:label>
<div @click.stop="">
Do you accept the
<a href="javascript:;" @click.stop="terms = true">terms</a>
and
<a href="javascript:;" @click.stop="conditions = true">conditions?</a>
</div>
</template>
</v-checkbox>
</v-col>
</v-row>
</v-container>
<v-card-actions>
<v-btn text @click="resetForm">Cancel</v-btn>
<v-spacer></v-spacer>
<v-btn
:disabled="!formIsValid"
text
color="primary"
type="submit"
>Register</v-btn>
</v-card-actions>
</v-form>
<v-dialog v-model="terms" width="70%">
<v-card>
<v-card-title class="title">Terms</v-card-title>
<v-card-text v-for="n in 5" :key="n">
{{ content }}
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn
text
color="purple"
@click="terms = false"
>Ok</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
<v-dialog v-model="conditions" width="70%">
<v-card>
<v-card-title class="title">Conditions</v-card-title>
<v-card-text v-for="n in 5" :key="n">
{{ content }}
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn
text
color="purple"
@click="conditions = false"
>Ok</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</v-card>
</template>
<script>
export default {
data () {
const defaultForm = Object.freeze({
first: '',
last: '',
bio: '',
favoriteAnimal: '',
age: null,
terms: false,
})
return {
form: Object.assign({}, defaultForm),
rules: {
age: [
val => val < 10 || `I don't believe you!`,
],
animal: [val => (val || '').length > 0 || 'This field is required'],
name: [val => (val || '').length > 0 || 'This field is required'],
},
animals: ['Dog', 'Cat', 'Rabbit', 'Turtle', 'Snake'],
conditions: false,
content: `Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget nulla. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur sodales ligula in libero. Sed dignissim lacinia nunc.`,
snackbar: false,
terms: false,
defaultForm,
}
},
computed: {
formIsValid () {
return (
this.form.first &&
this.form.last &&
this.form.favoriteAnimal &&
this.form.terms
)
},
},
methods: {
resetForm () {
this.form = Object.assign({}, this.defaultForm)
this.$refs.form.reset()
},
submit () {
this.snackbar = true
this.resetForm()
},
},
}
</script>
提示文本
在文本框组件使用 hint
来设置将提示的文本添加到文本字段下。使用 persistent-hint
保持提示文本在文本字段未被聚焦时保持可见性。
template
<template>
<v-form>
<v-container>
<v-row>
<v-col cols="12" sm="6">
<v-text-field
label="Your product or service"
value="Grocery delivery"
hint="For example, flowers or used cars"
></v-text-field>
</v-col>
<v-col cols="12" sm="6">
<v-text-field
label="Your landing page"
hint="www.example.com/page"
persistent-hint
></v-text-field>
</v-col>
<v-col cols="12" sm="6">
<v-text-field
label="Your product or service"
value="Grocery delivery"
hint="For example, flowers or used cars"
filled
></v-text-field>
</v-col>
<v-col cols="12" sm="6">
<v-text-field
label="Your landing page"
hint="www.example.com/page"
persistent-hint
filled
></v-text-field>
</v-col>
<v-col cols="12" sm="6">
<v-text-field
label="Your product or service"
value="Grocery delivery"
hint="For example, flowers or used cars"
outlined
></v-text-field>
</v-col>
<v-col cols="12" sm="6">
<v-text-field
label="Your landing page"
hint="www.example.com/page"
persistent-hint
outlined
></v-text-field>
</v-col>
</v-row>
</v-container>
</v-form>
</template>
前缀和后缀
prefix
和 suffix
属性允许你在文本字段旁添加一段不可修改的文本。
template
<template>
<v-container fluid>
<v-row>
<v-col cols="4">
<v-subheader>Prefix for dollar currency</v-subheader>
</v-col>
<v-col cols="8">
<v-text-field
label="Amount"
value="10.00"
prefix="$"
></v-text-field>
</v-col>
</v-row>
<v-row>
<v-col cols="4">
<v-subheader>Suffix for weight</v-subheader>
</v-col>
<v-col cols="8">
<v-text-field
label="Weight"
value="28.00"
suffix="lbs"
></v-text-field>
</v-col>
</v-row>
<v-row>
<v-col cols="4">
<v-subheader>Suffix for email domain</v-subheader>
</v-col>
<v-col cols="8">
<v-text-field
label="Email address"
value="example"
suffix="@gmail.com"
></v-text-field>
</v-col>
</v-row>
<v-row>
<v-col cols="4">
<v-subheader>Suffix for time zone</v-subheader>
</v-col>
<v-col cols="8">
<v-text-field
label="Label Text"
value="12:30:00"
type="time"
suffix="PST"
></v-text-field>
</v-col>
</v-row>
</v-container>
</template>
图标事件
click:prepend
, click:append
, click:append-outer
, 和 click:clear
将在单击相应的图标时发出。请注意,如果使用插槽,则不会触发这些事件。
template script
<template>
<v-form>
<v-container>
<v-row>
<v-col cols="12">
<v-text-field
v-model="message"
:append-icon="marker ? 'mdi-map-marker' : 'mdi-map-marker-off'"
:append-outer-icon="message ? 'mdi-send' : 'mdi-microphone'"
:prepend-icon="icon"
filled
clear-icon="mdi-close-circle"
clearable
label="Message"
type="text"
@click:append="toggleMarker"
@click:append-outer="sendMessage"
@click:prepend="changeIcon"
@click:clear="clearMessage"
></v-text-field>
</v-col>
</v-row>
</v-container>
</v-form>
</template>
<script>
export default {
data: () => ({
password: 'Password',
show: false,
message: 'Hey!',
marker: true,
iconIndex: 0,
icons: [
'mdi-emoticon',
'mdi-emoticon-cool',
'mdi-emoticon-dead',
'mdi-emoticon-excited',
'mdi-emoticon-happy',
'mdi-emoticon-neutral',
'mdi-emoticon-sad',
'mdi-emoticon-tongue',
],
}),
computed: {
icon () {
return this.icons[this.iconIndex]
},
},
methods: {
toggleMarker () {
this.marker = !this.marker
},
sendMessage () {
this.resetIcon()
this.clearMessage()
},
clearMessage () {
this.message = ''
},
resetIcon () {
this.iconIndex = 0
},
changeIcon () {
this.iconIndex === this.icons.length - 1
? this.iconIndex = 0
: this.iconIndex++
},
},
}
</script>
图标插槽
可以使用插槽来扩展输入的功能,而不是使用 prepend / append / append-outer 图标。
template script
<template>
<v-form>
<v-container>
<v-row>
<v-col cols="12">
<v-text-field
v-model="message"
outlined
clearable
label="Message"
type="text"
>
<template v-slot:prepend>
<v-tooltip
bottom
>
<template v-slot:activator="{ on }">
<v-icon v-on="on">mdi-help-circle-outline</v-icon>
</template>
I'm a tooltip
</v-tooltip>
</template>
<template v-slot:append>
<v-fade-transition leave-absolute>
<v-progress-circular
v-if="loading"
size="24"
color="info"
indeterminate
></v-progress-circular>
<img v-else width="24" height="24" src="https://cdn.vuetifyjs.com/images/logos/v-alt.svg" alt="">
</v-fade-transition>
</template>
<template v-slot:append-outer>
<v-menu
style="top: -12px"
offset-y
>
<template v-slot:activator="{ on }">
<v-btn v-on="on">
<v-icon left>mdi-menu</v-icon>
Menu
</v-btn>
</template>
<v-card>
<v-card-text class="pa-6">
<v-btn large flat color="primary" @click="clickMe"><v-icon left>mdi-target</v-icon>Click me</v-btn>
</v-card-text>
</v-card>
</v-menu>
</template>
</v-text-field>
</v-col>
</v-row>
</v-container>
</v-form>
</template>
<script>
export default {
data: () => ({
message: 'Hey!',
loading: false,
}),
methods: {
clickMe () {
this.loading = true
this.message = 'Wait for it...'
setTimeout(() => {
this.loading = false
this.message = 'You\'ve clicked me!'
}, 2000)
},
},
}
</script>
标签插槽
文本字段标签可以在 label
插槽中定义 - 允许使用 HTML 内容
template
<template>
<v-form>
<v-container>
<v-text-field>
<template v-slot:label>
What about <strong>icon</strong> here? <v-icon style="vertical-align: middle">find_in_page</v-icon>
</template>
</v-text-field>
</v-container>
</v-form>
</template>
验证
Vuetify包含简单的验证通过使用 rules
属性,这个属性接受一个回调函数组,在验证规则时,当前的 v-model 值将被传递给回调函数,这个回调函数必须返回 ture
或 String
或者错误信息。
template script
<template>
<v-form>
<v-container>
<v-row>
<v-col cols="12" sm="6">
<v-text-field
v-model="title"
:rules="[rules.required, rules.counter]"
label="Title"
counter
maxlength="20"
></v-text-field>
</v-col>
<v-col cols="12" sm="6">
<v-text-field
v-model="email"
:rules="[rules.required, rules.email]"
label="E-mail"
></v-text-field>
</v-col>
</v-row>
</v-container>
</v-form>
</template>
<script>
export default {
data () {
return {
title: 'Preliminary report',
email: '',
rules: {
required: value => !!value || 'Required.',
counter: value => value.length <= 20 || 'Max 20 characters',
email: value => {
const pattern = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
return pattern.test(value) || 'Invalid e-mail.'
},
},
}
},
}
</script>
带计数器的全宽文本框
全宽文本框允许你创建一个不限制输入的文本框,在下面的例子中,我们是用 v-divider
来分隔文本框。
template script
<template>
<v-form>
<v-autocomplete
v-model="selected"
:items="['Trevor Handsen', 'Alex Nelson']"
chips
label="To"
full-width
hide-details
hide-no-data
hide-selected
multiple
single-line
></v-autocomplete>
<v-divider></v-divider>
<v-text-field
label="Subject"
value="Plans for the weekend"
single-line
full-width
hide-details
></v-text-field>
<v-divider></v-divider>
<v-textarea
v-model="title"
label="Message"
counter
maxlength="120"
full-width
single-line
></v-textarea>
</v-form>
</template>
<script>
export default {
data () {
return {
selected: ['Trevor Handsen'],
items: ['Trevor Handsen', 'Alex Nelson'],
title: 'Hi,\nI just wanted to check in and see if you had any plans the upcoming weekend. We are thinking of heading up to Napa',
}
},
}
</script>
进度条
你可以用一个进度条来替换下划线,你可以使用与文本框具有相同颜色的默认的不确定进度的进度条,你也可以使用 progress
插槽来自定义进度条。
template script
<template>
<v-container fluid>
<v-checkbox v-model="custom" label="Custom progress bar"></v-checkbox>
<v-text-field
v-model="value"
color="cyan darken"
label="Text field"
placeholder="Start typing..."
loading
>
<template v-slot:progress>
<v-progress-linear
v-if="custom"
:value="progress"
:color="color"
absolute
height="7"
></v-progress-linear>
</template>
</v-text-field>
</v-container>
</template>
<script>
export default {
data: () => ({
value: '',
custom: true,
}),
computed: {
progress () {
return Math.min(100, this.value.length * 10)
},
color () {
return ['error', 'warning', 'success'][Math.floor(this.progress / 40)]
},
},
}
</script>
自定义验证
虽然内置的 v-form
组件以及第三方插件比如 vuelidate or vee-validation 可以帮助你简化验证过程,但你仍可以简单的自行控制它。
template script
<template>
<v-row justify="center">
<v-col cols="12" sm="10" md="8" lg="6">
<v-card ref="form">
<v-card-text>
<v-text-field
ref="name"
v-model="name"
:rules="[() => !!name || 'This field is required']"
:error-messages="errorMessages"
label="Full Name"
placeholder="John Doe"
required
></v-text-field>
<v-text-field
ref="address"
v-model="address"
:rules="[
() => !!address || 'This field is required',
() => !!address && address.length <= 25 || 'Address must be less than 25 characters',
addressCheck
]"
label="Address Line"
placeholder="Snowy Rock Pl"
counter="25"
required
></v-text-field>
<v-text-field
ref="city"
v-model="city"
:rules="[() => !!city || 'This field is required', addressCheck]"
label="City"
placeholder="El Paso"
required
></v-text-field>
<v-text-field
ref="state"
v-model="state"
:rules="[() => !!state || 'This field is required']"
label="State/Province/Region"
required
placeholder="TX"
></v-text-field>
<v-text-field
ref="zip"
v-model="zip"
:rules="[() => !!zip || 'This field is required']"
label="ZIP / Postal Code"
required
placeholder="79938"
></v-text-field>
<v-autocomplete
ref="country"
v-model="country"
:rules="[() => !!country || 'This field is required']"
:items="countries"
label="Country"
placeholder="Select..."
required
></v-autocomplete>
</v-card-text>
<v-divider class="mt-12"></v-divider>
<v-card-actions>
<v-btn text>Cancel</v-btn>
<v-spacer></v-spacer>
<v-slide-x-reverse-transition>
<v-tooltip
v-if="formHasErrors"
left
>
<template v-slot:activator="{ on }">
<v-btn
icon
class="my-0"
@click="resetForm"
v-on="on"
>
<v-icon>mdi-refresh</v-icon>
</v-btn>
</template>
<span>Refresh form</span>
</v-tooltip>
</v-slide-x-reverse-transition>
<v-btn color="primary" text @click="submit">Submit</v-btn>
</v-card-actions>
</v-card>
</v-col>
</v-row>
</template>
<script>
export default {
data: () => ({
countries: ['Afghanistan', 'Albania', 'Algeria', 'Andorra', 'Angola', 'Anguilla', 'Antigua & Barbuda', 'Argentina', 'Armenia', 'Aruba', 'Australia', 'Austria', 'Azerbaijan', 'Bahamas', 'Bahrain', 'Bangladesh', 'Barbados', 'Belarus', 'Belgium', 'Belize', 'Benin', 'Bermuda', 'Bhutan', 'Bolivia', 'Bosnia & Herzegovina', 'Botswana', 'Brazil', 'British Virgin Islands', 'Brunei', 'Bulgaria', 'Burkina Faso', 'Burundi', 'Cambodia', 'Cameroon', 'Cape Verde', 'Cayman Islands', 'Chad', 'Chile', 'China', 'Colombia', 'Congo', 'Cook Islands', 'Costa Rica', 'Cote D Ivoire', 'Croatia', 'Cruise Ship', 'Cuba', 'Cyprus', 'Czech Republic', 'Denmark', 'Djibouti', 'Dominica', 'Dominican Republic', 'Ecuador', 'Egypt', 'El Salvador', 'Equatorial Guinea', 'Estonia', 'Ethiopia', 'Falkland Islands', 'Faroe Islands', 'Fiji', 'Finland', 'France', 'French Polynesia', 'French West Indies', 'Gabon', 'Gambia', 'Georgia', 'Germany', 'Ghana', 'Gibraltar', 'Greece', 'Greenland', 'Grenada', 'Guam', 'Guatemala', 'Guernsey', 'Guinea', 'Guinea Bissau', 'Guyana', 'Haiti', 'Honduras', 'Hong Kong', 'Hungary', 'Iceland', 'India', 'Indonesia', 'Iran', 'Iraq', 'Ireland', 'Isle of Man', 'Israel', 'Italy', 'Jamaica', 'Japan', 'Jersey', 'Jordan', 'Kazakhstan', 'Kenya', 'Kuwait', 'Kyrgyz Republic', 'Laos', 'Latvia', 'Lebanon', 'Lesotho', 'Liberia', 'Libya', 'Liechtenstein', 'Lithuania', 'Luxembourg', 'Macau', 'Macedonia', 'Madagascar', 'Malawi', 'Malaysia', 'Maldives', 'Mali', 'Malta', 'Mauritania', 'Mauritius', 'Mexico', 'Moldova', 'Monaco', 'Mongolia', 'Montenegro', 'Montserrat', 'Morocco', 'Mozambique', 'Namibia', 'Nepal', 'Netherlands', 'Netherlands Antilles', 'New Caledonia', 'New Zealand', 'Nicaragua', 'Niger', 'Nigeria', 'Norway', 'Oman', 'Pakistan', 'Palestine', 'Panama', 'Papua New Guinea', 'Paraguay', 'Peru', 'Philippines', 'Poland', 'Portugal', 'Puerto Rico', 'Qatar', 'Reunion', 'Romania', 'Russia', 'Rwanda', 'Saint Pierre & Miquelon', 'Samoa', 'San Marino', 'Satellite', 'Saudi Arabia', 'Senegal', 'Serbia', 'Seychelles', 'Sierra Leone', 'Singapore', 'Slovakia', 'Slovenia', 'South Africa', 'South Korea', 'Spain', 'Sri Lanka', 'St Kitts & Nevis', 'St Lucia', 'St Vincent', 'St. Lucia', 'Sudan', 'Suriname', 'Swaziland', 'Sweden', 'Switzerland', 'Syria', 'Taiwan', 'Tajikistan', 'Tanzania', 'Thailand', "Timor L'Este", 'Togo', 'Tonga', 'Trinidad & Tobago', 'Tunisia', 'Turkey', 'Turkmenistan', 'Turks & Caicos', 'Uganda', 'Ukraine', 'United Arab Emirates', 'United Kingdom', 'United States', 'Uruguay', 'Uzbekistan', 'Venezuela', 'Vietnam', 'Virgin Islands (US)', 'Yemen', 'Zambia', 'Zimbabwe'],
errorMessages: '',
name: null,
address: null,
city: null,
state: null,
zip: null,
country: null,
formHasErrors: false,
}),
computed: {
form () {
return {
name: this.name,
address: this.address,
city: this.city,
state: this.state,
zip: this.zip,
country: this.country,
}
},
},
watch: {
name () {
this.errorMessages = ''
},
},
methods: {
addressCheck () {
this.errorMessages = this.address && !this.name
? 'Hey! I\'m required'
: ''
return true
},
resetForm () {
this.errorMessages = []
this.formHasErrors = false
Object.keys(this.form).forEach(f => {
this.$refs[f].reset()
})
},
submit () {
this.formHasErrors = false
Object.keys(this.form).forEach(f => {
if (!this.form[f]) this.formHasErrors = true
this.$refs[f].validate(true)
})
},
},
}
</script>