Vue自定义组件如何实现v-model数据双向绑定

为了保证数据完整性,Vue在自定义组件的props定义中,只允许父组件向子组件传递数据,子组件不能直接修改props中的数据,在实际项目中有很多需要子组件内部更新属性,并同步给父组件的情况,也就是v-model数据双向绑定,那自定义组件如何实现v-model数据双向绑定呢?

在 Vue 中,自定义组件可以通过 props 传递数据,然后通过 emit 触发事件向父级组件发送更新。这样就可以实现类似 v-model 的双向绑定效果。
具体步骤如下:

  1. 在自定义组件中定义一个 prop 用于接收值,例如:
1
props: ['value'] 
  1. 在自定义组件中维护该值的内部状态,例如:
1
2
3
4
5
data() {
return {
innerValue: this.value
}
}
  1. 在自定义组件中定义一个 model 属性,例如:
1
2
3
4
model: {
prop: 'value',
event: 'input'
}
  1. 然后在内部状态发生变化时触发该事件,例如:
1
this.$emit('input', this.innerValue) 
  1. 最后,在使用自定义组件的父级组件中,使用 v-model 双向绑定 prop 和 emit,例如:
1
<my-component v-model="someValue"></my-component> 

这相当于:

1
2
3
4
<my-component 
:value="someValue"
@input="someValue = $event"
></my-component>

通过这 5 个步骤,我们就实现了自定义组件的 v-model 效果,以下是一个完整示例:

父组件:

1
2
3
4
5
6
7
8
9
10
11
12
13
<template>
<my-component v-model="message"></my-component>
</template>

<script>
export default {
data() {
return {
message: 'Hello'
}
}
}
</script>

自定义组件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<template>
<input type="text" :value="innerValue" @input="onInput">
</template>

<script>
export default {
props: ['value'],
data() {
return {
innerValue: this.value
}
},
model: {
prop: 'value',
event: 'input'
}
methods: {
onInput(e) {
this.innerValue = e.target.value
this.$emit('input', this.innerValue)
}
}
}
</script>

本文永久链接: https://www.mulianju.com/vue-v-model/