前言
v-model
实际上就是 $emit('input')
以及 props:value
的组合语法糖。
1.封装自定义组件
要在 Vue 中实现自定义组件的 v-model
功能,你可以通过使用 model
选项来定义组件的 prop
和事件。以下是一个示例代码,演示如何实现一个自定义组件并使用 v-model 来进行双向绑定:
<template>
<div>
<input :value="value" @input="updateValue($event.target.value)">
</div>
</template>
<script>
export default {
props: {
value: String
},
model: {
prop: 'value',
event: 'input'
},
methods: {
updateValue(value) {
this.$emit('input', value);
}
}
};
</script>
在上面的示例中,我们创建了一个简单的自定义输入框组件,通过 value
prop 来接收父组件传递的值,并通过 updateValue
方法来触发 input
事件并将新的值传递给父组件。在组件的 model
选项中,我们定义了 prop 和事件的名称,以便 Vue 知道如何处理 v-model
。
2.使用自定义组件
在父组件中,你可以像下面这样使用自定义组件,并通过 v-model
来进行双向绑定:
<template>
<div>
<CustomInput v-model="inputValue" />
<p>Input value: {{ inputValue }}</p>
</div>
</template>
<script>
import CustomInput from './CustomInput.vue';
export default {
components: {
CustomInput
},
data() {
return {
inputValue: ''
};
}
};
</script>
通过以上方式,你可以在 Vue 中实现自定义组件的 v-model
功能,实现双向绑定的效果。
3.完善自定义组件
问题
上面有一个问题是props是单向数据流,不应该在一个子组件内部改变 props!
优化完善如下
<template>
<div>
<input type="number" :value="currentValue" @input="changeValue"/>
</div>
</template>
<script>
export default {
props:{
value:{
type: Number
}
},
computed(){
return {
currentValue: this.value
}
}
methods:{
changeValue(e){
this.currentValue = parseInt(e.target.value);
this.$emit('input', this.currentValue);
}
}
};
</script>