v-model的原理详解
v-model的本质就是一个语法糖,实际上就是 :value="msg"
与 @input="msg = $event.target.value"
的简写。
:value="msg"
从数据单向绑定到input框,当data数据中的msg内容一旦改变,而input框数据也随之改变。
@input="msg = $event.target.value"
是为input框绑定了input事件,内容改变则触发,而在触发时又把这个input框的value值赋值给了data数据中的msg。
原本使用porps和$emit实现的父子组件通信。
这下面的代码就实现了父子组件属性的双向绑定。
而这其中父组件中的子标签属性 :value="msg" @input="sendMsg"
是与 使用 v-model:"msg"
等价的,因为sendMsg(value){ console.log(value) this.msg = value }
方法的内容是与v-model原理中的@input="msg = $event.target.value"
是一模一样的意思,所以在父组件中我们可以使用以下代码来与子组件双向绑定
<!-- 结构 -->
<template>
<div id="app">
<MyInput v-model="msg"></MyInput>
</div>
</template>
<!-- 行为 -->
<script>
import MyInput from './components/MyInput.vue';
export default {
name: "App",
data() {
return {
msg: "你好!vue",
};
},
components:{
MyInput
},
};
</script>
<!-- 样式 -->
<style>
#app {
width: 100%;
height: 600px;
background-color: skyblue;
overflow: hidden;
}
</style>
而子组件则需要注意的是,使用 props:{ value:String },
来接受父组件数据,必须是vaule:
<template>
<input type="text" :value="value"
@input="fun($event.target.value)">
</template>
<script>
export default {
props:{
value:String
},![在这里插入图片描述](https://img-blog.csdnimg.cn/2ce2b0549f674812a0fc5ad9feb65559.png#pic_center)
methods:{
fun(e){
this.$emit('input',e)
}
}
}
</script>
.sync修饰符
使用v-model有一个坏处就是,子组件接收数据的键只可以使用value props:{ value:String }
,而这个修饰符.sync
就可以解决这个问题。
子组件中将修改触发方法。
<template>
<input type="text" :value="msg"
@input="fun($event.target.value)">
</template>
<script>
export default {
props:{
msg:String
},
methods:{
fun(e){
//修改点update:要修改的属性名称
this.$emit('update:msg',e)
}
}
}
</script>
父组件中的修改点:
<!-- 结构 -->
<template>
<div id="app">
<!-- 只需修改为 :传递数据名.sync="传递数据名" -->
<MyInput :msg.sync = "msg"></MyInput>
</div>
</template>
<!-- 行为 -->
<script>
import MyInput from './components/MyInput.vue';
export default {
name: "App",
data() {
return {
msg: "你好!vue",
};
},
components:{
MyInput
},
};
</script>
<!-- 样式 -->
<style>
#app {
width: 100%;
height: 600px;
background-color: skyblue;
overflow: hidden;
}
</style>