示例代码
child.vue
<template>
<div class="child_style">
我是child:
<input :value="value" @input="emitFather">
</div>
</template>
<script>
export default {
model: {
prop: 'value',
event: 'input'
},
props: ['value'],
methods: {
emitFather(e) {
this.$emit('input');
},
}
}
</script>
father.vue
<template>
<div class="father_style">
我是father:{{vModelValue}}
<child v-model="vModelValue"></child>
<button @click="changeVModelValue">改变vModelValue</button>
</div>
</template>
<script>
import child from './child.vue'
export default {
components: {
child
},
data() {
return {
vModelValue: 2020
}
},
methods: {
changeVModelValue() {
this.vModelValue = 2999;
}
}
}
</script>
自定义组件中v-model的机制
首先,需要明确的是v-model
只是一个语法糖,下面的父组件方式1和方式2在使用效果上是完全一样的。
// 因为这里的的child
组件内以input
框为主,而input
框的默认@input
事件是会携带当前输入框内的值的。
//方式1
<child v-model="vModelValue"></child>
//方式2
<child :value="vModelValue" @input="value = $event.target.value"></child>
父组件把值A传给子组件,值A在子组件内变为了值B,值B在子组件内发生改变,然后通过触发方法再把值B传出来,最后将值B赋给值A。
在Vue.js官方文档中有说到,v-model
默认使用名为 value
的 prop 和名为 input
的事件。也就是前面示例代码child.vue
中的10-13行其实是可以省略不写的。
子组件中的model选项
这个配置是可以更改的,我们试着在子组件中将代码改为如下。
model: {
prop: 'newValue',
event: 'newEvent'
},
因为接收的属性名称已经改变了,随之相应需要改变的是child.vue
的第4行与第14行。
// 第4行
<input :value="newValue" @input="emitFather">
// 第14行
props: ['newValue'],
因为父组件接收的事件名也已经发生改变,所以child.vue
内还需要改变第17行
emitFather(e) {
this.$emit('newEvent');
},
可以发现,当父组件使用上述所说的方式1时,更改子组件的v-model配置是完全不影响父组件的。
当使用方式2时,父组件还要随着子组件v-model配置的更改改变接收的事件名称和传参名称。