使用v-model
指令创建一个双向绑定<input>
元素和数据属性。
<template>
<h1>v-model Example</h1>
<p>Write something, and see the 'inputValue' data property update automatically.</p>
<input type="text" v-model="inputValue">
<p>inputValue property: "{{ inputValue }}"</p>
</template>
运行示例 »
请参阅下面的更多示例。
这个v-model
指令用于在表单输入元素之间或 Vue 实例属性和组件之间创建双向绑定。
v-model
可以使用的表单输入元素v-model
是<input>
,<select>
和<textarea>
。
双向绑定和v-model
表单输入元素的工作方式如下:
(参见上面的示例和下面的示例 1。)
v-model
什么时候v-model
用于组件,组件接口必须正确设置props
和emits
从而实现双向绑定。
双向绑定和v-model
在组件上的工作方式如下:
什么时候v-model
用于组件,默认 prop 名称为“modelValue”,默认发出事件名称为“update:modelValue”。 (看示例2和示例3.)
什么时候v-model
在组件上使用,我们可以使用计算属性,而不是使用 Vue 实例数据属性get()
和set()
方法。 (参见示例4)
可以使用以下命令设置与默认“modelValue”和“update:modelValue”不同的 props 和 Emits 名称v-model:
。 (参见示例5)
要让多个值作为双向绑定连接到组件,我们必须用自己的值定义每个这样的值v-model
。 (参见示例6)
修饰符 | 细节 |
---|---|
.lazy |
这个change Vue 使用事件而不是input 何时同步的事件。这意味着用户必须首先修改输入,然后在更新实例属性值之前将焦点从输入元素移开。 (参见示例7) |
.number |
将输入类型转换为数字。这是在使用时自动完成的<input type="number"> 。 |
.trim |
删除输入开头和结尾的空格。 (参见示例8) |
风俗 | 创建自定义修饰符v-model ,我们首先需要定义一个 prop 'modelModifiers' 来存储新的修饰符。修饰符功能写在方法中。如果设置了修饰符,则在将值发送回父组件之前,会在方法中运行适当的代码。 (参见示例9) |
使用滑块 (<input type="range">
) 更改“inputValue”属性值。这<input type="text">
元素会自动更新,因为它绑定到 'inputValue' 属性v-model
。
<template>
<h1>v-model Example</h1>
<p>Drag the slider to change the 'inputValue' data property, and see the input text field update automatically because of the two-way binding from v-model.</p>
<input type="range" min="-50" max="50" v-on:input="sliderChange" value="4">
<p>inputValue property: "{{ inputValue }}"</p>
<input type="text" v-model="inputValue">
</template>
<script>
export default {
data() {
return {
inputValue: null
};
},
methods: {
sliderChange(evt) {
this.inputValue = evt.target.value
}
}
}
</script>
运行示例 »
使用v-model
在组件上props
和emits
从而使变化<input>
元素更新父级的“text”属性。
App.vue
:
<template>
<h2>Example v-model Directive</h2>
<p>App.vue 'text' property: "{{ text }}"</p>
<comp-one v-model="text"/>
</template>
<script>
export default {
data() {
return {
text: 'Say Cheese'
}
}
}
</script>
CompOne.vue
:
<template>
<div>
<h3>Component</h3>
<p>Write something in the text input field below to see that changes here are emitted from the component, and the parent 'text' property gets updated by the use of v-model.</p>
<input
:value="modelValue"
@input="$emit('update:modelValue', $event.target.value)"
/>
</div>
</template>
<script>
export default {
props: ['modelValue'],
emits: ['update:modelValue']
}
</script>
<style scoped>
div {
border: solid black 1px;
padding: 10px;
margin: 20px 0;
max-width: 500px;
}
</style>
运行示例 »
使用v-model
在组件上更清楚地演示双向绑定。组件可以更新父“text”属性,并且当父“text”属性更改时组件也会更新。
App.vue
:
<template>
<h2>Example v-model Directive</h2>
<p>App.vue 'text' property: "<pre>{{ text }}</pre>"</p>
<button v-on:click="this.text = 'Hello!'">text='Hello!'</button>
<comp-one v-model="text"/>
</template>
<script>
export default {
data() {
return {
text: 'Say Cheese'
}
}
}
</script>
<style>
pre {
display: inline;
background-color: yellow;
}
</style>
CompOne.vue
:
<template>
<div>
<h3>Component</h3>
<p>Two-way binding on component with v-model:</p>
<ol>
<li>The component can update the 'text' property (using text field).</li>
<li>The component gets updated when the 'text' property is changed (using button).</li>
</ol>
<input
:value="modelValue"
@input="$emit('update:modelValue', $event.target.value)"
/>
</div>
</template>
<script>
export default {
props: ['modelValue'],
emits: ['update:modelValue']
}
</script>
<style scoped>
div {
border: solid black 1px;
padding: 10px;
margin: 20px 0;
max-width: 600px;
}
</style>
运行示例 »
使用v-model
与计算值get()
和set()
组件内部的函数。
CompOne.vue
:
<template>
<div>
<h3>Component</h3>
<p>Two-way binding on component with v-model:</p>
<ol>
<li>The component can update the 'text' property (using text field).</li>
<li>The component gets updated when the 'text' property is changed (using button).</li>
</ol>
<input v-model="inpVal"/>
</div>
</template>
<script>
export default {
props: ['modelValue'],
emits: ['update:modelValue'],
computed: {
inpVal: {
get() {
return this.modelValue;
},
set(inpVal) {
this.$emit('update:modelValue',inpVal)
}
}
}
}
</script>
<style scoped>
div {
border: solid black 1px;
padding: 10px;
margin: 20px 0;
max-width: 600px;
}
</style>
运行示例 »
使用v-model:message
在组件上将默认道具名称“modelValue”重命名为“message”。
App.vue
:
<template>
<h2>Example v-model Directive</h2>
<p>App.vue 'text' property: "<pre>{{ text }}</pre>"</p>
<button v-on:click="this.text = 'Hello!'">text='Hello!'</button>
<comp-one v-model:message="text"/>
</template>
<script>
export default {
data() {
return {
text: 'Say Cheese'
}
}
}
</script>
<style>
pre {
display: inline;
background-color: yellow;
}
</style>
CompOne.vue
:
<template>
<div>
<h3>Component</h3>
<p>Two-way binding on component with v-model:</p>
<ol>
<li>The component can update the 'text' property (using text field).</li>
<li>The component gets updated when the 'text' property is changed (using button).</li>
</ol>
<input
:value="message"
@input="$emit('update:message', $event.target.value)"
/>
</div>
</template>
<script>
export default {
props: ['message'],
emits: ['update:message']
}
</script>
<style scoped>
div {
border: solid black 1px;
padding: 10px;
margin: 20px 0;
max-width: 600px;
}
</style>
运行示例 »
使用v-model
在组件上两次以创建具有两个值的双向绑定。
App.vue
:
<template>
<h2>Example v-model Directive</h2>
<p>Name: "<pre>{{ name }}</pre>"</p>
<p>Height: <pre>{{ height }}</pre> cm</p>
<comp-one
v-model:name="name"
v-model:height="height"
/>
</template>
<script>
export default {
data() {
return {
name: 'Olaf',
height: 120
}
}
}
</script>
<style>
pre {
display: inline;
background-color: yellow;
}
</style>
CompOne.vue
:
<template>
<div>
<h3>Component</h3>
<p>Two inputs are bound to the component with v-model through props and emits.</p>
<p>
<label>
Name:
<input
type="text"
:value="name"
@input="$emit('update:name', $event.target.value)"
/>
</label>
</p>
<p>
<label>
Height:
<input
type="range"
:value="height"
@input="$emit('update:height', $event.target.value)"
min="50"
max="200"
/>
{{ this.$props.height }} cm
</label>
</p>
</div>
</template>
<script>
export default {
props: ['name','height'],
emits: ['update:name','update:height']
}
</script>
<style scoped>
div {
border: solid black 1px;
padding: 10px;
margin: 20px 0;
max-width: 300px;
}
</style>
运行示例 »
使用.lazy
这样用户必须首先修改输入元素,然后在属性更新之前将焦点从输入元素上移开v-model
。
<template>
<h1>v-model Example</h1>
<p>Using the '.lazy' modifier, you must first write something, then click somewhere else, or use the tab key to switch focus away from the input element, before the property get updated.</p>
<input type="text" v-model.lazy="inputValue">
<p>inputValue property: "{{ inputValue }}"</p>
</template>
<script>
export default {
data() {
return {
inputValue: null
};
}
}
</script>
运行示例 »
使用.lazy
这样用户必须首先修改输入元素,然后在属性更新之前将焦点从输入元素上移开v-model
。
<template>
<h1>v-model Example</h1>
<p>Using the '.trim' modifier will remove any white spaces at the start and end of the input.</p>
<p>Add white spaces at the start and end in the input fields below to see the difference with or with out '.trim'.</p>
<p>No '.trim': <input type="text" v-model="inputVal1"> "<pre>{{ inputVal1 }}</pre>"</p>
<p>With '.trim': <input type="text" v-model.trim="inputVal2"> "<pre>{{ inputVal2 }}</pre>"</p>
</template>
<script>
export default {
data() {
return {
inputVal1: 'Hello',
inputVal2: 'Hi'
};
}
}
</script>
<style>
pre {
display: inline;
background-color: lightgreen;
}
</style>
运行示例 »
使用自定义.allCapital
修饰符将输入中的所有字符转换为大写,如果.allCapital
修改器已设置。
App.vue
:
<template>
<h2>Example v-model Directive</h2>
<p>App.vue 'text' property: "{{ text }}"</p>
<comp-one v-model.allCapital="text"/>
</template>
<script>
export default {
data() {
return {
text: ''
}
}
}
</script>
CompOne.vue
:
<template>
<div>
<h3>Component</h3>
<p>Write something in the text input field below. Click somewhere else or use the tab key to shift focus away from the input element to see the effect of the custom 'allCapital' modifier.</p>
<input
:value="modelValue"
@change="this.emitVal"
/>
</div>
</template>
<script>
export default {
props: {
modelValue: String,
modelModifiers: {
// modelModifiers is an empty object initially.
// Modifiers set on the component will be stored here.
default: () => ({})
}
},
emits: ['update:modelValue'],
methods: {
emitVal(e) {
let value = e.target.value
if (this.modelModifiers.allCapital) {
value = value.toUpperCase()
}
this.$emit('update:modelValue', value)
}
}
}
</script>
<style scoped>
div {
border: solid black 1px;
padding: 10px;
margin: 20px 0;
max-width: 500px;
}
</style>
运行示例 »
Vue教程:Vue 组件
Vue教程:Vue 道具
Vue教程:Vue $emit() 方法
Vue教程:Vue 计算属性
Vue参考:Vue $emit() 方法
Vue参考:Vue $props 对象
JavaScript 教程:JavaScript 对象访问器