组件的 v-model
表单的 v-model
在开发中使用表单时,我们通常会使用v-model来进行数据的双向绑定。
<input v-model='message' />
v-model默认帮我们做了两件事:
-
对
value属性进行数据绑定 -
对
input事件进行监听
即,上面的代码相当于:
<input :value='message' @input='message = $event.target.value' />
组件的 v-model
v-model 属性也可以用在组件上。
什么情况下需要用到组件的 v-model 属性?
有些时候我们会把常用的表单控件封装成组件来使用,当我们在使用这些组件时肯定是希望像使用表单元素一样,实现双向数据绑定,这个时候就可以使用组件的 v-model 属性来实现。
组件上的 v-model 也默认帮我们做了两件事:
-
对
modelValue属性进行数据绑定 -
对
update:modelValue事件进行监听
<template>
<div>
<home v-model='message' />
// 相当于
<home :model-value='message' @update:model-value='message = $event' />
</div>
</template>
import Home from '@/page/Home.vue'
export default {
components:{
Home,
},
data() {
return {
message: 'hello world'
}
}
}
在 home 组件中,我们需要
export default {
props: ['modelValue'],
emits: ['update:modelValue']
}
案例:我们封装了一个 my-input 组件,然后在父组件中使用 v-model 来对它进行数据的双向绑定:
<template>
<div>
<my-input v-model='message' />
<!-- <my-input :model-value='message' @update:model-value='message = $event' /> -->
</div>
</template>
import MyInput from '@/page/MyInput.vue'
export default {
components:{
MyInput,
},
data() {
message: ''
}
}
在子组件中:
// my-input 组件
<template>
<div>
<input :value='modelValue' @input='onInput' />
</div>
</template>
export default {
props: ['modelValue'],
emits: ['update:modelValue'],
methods: {
onInput(e) {
this.$emit('update:modelValue', e.target.value)
}
}
}
问题一:可不可以用 v-model 来替换上面 input 标签里的 :value='modelValue' @input='onInput'呢?
即:
<input v-model='modelValue' />
不可以。有两个原因:
- 如果写成
v-model的形式,实际上相当于下面的代码:
<input :value='modelValue' @input='modelValue = $event.target.value' />
这个时候不管怎么改变输入框的值,都只会修改 props 中的 modelValue ,而不会改变父组件中的值
- 在开发过程过中,一定不要直接来修改
props中的数据
问题二:如果我们依然希望通过 v-model 的方式来实现的话,应该怎么做呢?这里我们用到计算属性 computed
<input v-model='finalValue' />
export default {
props: ['modelValue'],
emits: ['update:modelValue'],
computed: {
finalValue: {
set(val) {
this.$emit('update:modelValue', val)
},
get() {
return this.modelValue
}
}
}
}