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},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>