最近在Vue官方文档看到自定义事件的表单输入组件时,纠结了亿会儿才绕过弯,所以决定总结一下让自己思路更清晰。
了解过vue的都知道v-model是用于表单数据的双向绑定,但到底怎么实现的,可能有一部分人都答不上来了。今天我们就来聊一聊v-model双向数据绑定的原理及如何在组件上使用。
v-model语法糖
v-model用于表单数据的双向绑定,我们使用时一般是这样写的:
<div id="app">
<input v-model="msg">
</div>
new Vue({
el: '#app',
data: {
msg: '你好啊'
}
});
通过该语句实现price变量与输入值双向绑定
实际上v-model只是一个语法糖,真正的实现是这样的:
<input type="text" :value="msg" @input="msg=$event.target.value">
以上代码就可以看出来实现双向绑定就完成了两个操作:
- 将输入框的值绑定到msg变量上,这个是单向绑定,意味着改变msg变量的值会改变input的value
- 在单向数据绑定的基础上,监听input事件(input输入框都有该事件,当输入内容是自动触发该事件),当输入框输入内容时(value发生改变)就可以改变msg的值
自定义组件使用v-model
由v-model的语法糖可以看出,要自定义组件使用v-model,应该有以下操作:
- 通过v-bind绑定一个value属性
- 通过v-on或@指令给当前元素绑定input事件,触发事件并传入新值
话不多说,上代码!
//父组件
<template>
<div>
这里是父组件<br>
{{ name }}
<hr>
<Son1 v-model="name"></Son1>
<!--3.父组件的input事件被触发,将传来的值赋给父组件的变量name,实现输入框value到父元素的name的单向绑定-->
<!-- 4.父组件value的值绑定到name-->
<!-- 相当于<Son1 :value='name' @input="name=arguments[0]"></Son1> -->
</div>
</div>
</template>
<script>
import Son1 from './components/Son1.vue'
export default {
name: 'App',
components: {
Son1
},
data () {
return {
name: '小红'
}
}
}
</script>
//子组件
<template>
<div class="son">
这里是子组件<br>
{{ value }}
<!--
也可以这样写实现input输入的双向绑定
<input
type="text"
:value="value"
@input="$emit('input',$event.target.value)"
/> -->
<!-- 1.当点击按钮时,触发changeName方法 -->
<button @click="changeName">修改value</button>
</div>
</template>
<script>
export default {
name: 'Son1',
// 5、将父组件的value值通过props传递给子组件
props: ['value'],
methods: {
changeName () {
// 2.手动触发父组件的input事件并将值传给父组件
this.$emit('input', '小明')
}
}
}
</script>
vue 在父子组件传值时,除了传统的父组件使用:属性去传值外,还可以使用父组件v-model传值,子组件props:[‘value’]接收,而子组件也可以通过this.$emit(‘input’, ‘小明’),去改变父组件中v-model 和 子组件中value的值 。
最后小小总结一下:
v-bind只能实现单向绑定
v-model(v-bind+触发的input事件)实现双向绑定
如果大家有什么意见或建议希望大家在评论区多多交流,谢谢😊