将父传子,子传父稍微结合一下,实现父子组件通信双向绑定。最终实现在子组件的输入框中输入数据,实时改变父组件中的数据
同样的,先注册子组件和父组件
const cpn = {
template: '#cnp',
props:{
num1:Number,
num2:Number
},
}
const app = new Vue({
el: "#app",
data: {
number1:1,
number2:0
},
components: {
cpn
},
})
<template id="cnp">
<div>
<h2>data:{{num1}}</h2>
<!-- v-model 等于 :value=''+ @input=' =$event.target.value'-->
<input type="text" :value='dnumber1' @input ='num1Input'>
<h2>data:{{num2}}</h2>
<input type="text" :value='dnumber2' @input ='num2Input'>
</div>
</template>
<div id="app">
//将父组件中的数据绑定到子组件上
<cpn
:num1='number1'
:num2='number2'
>
</cpn>
</div>
需要注意的是使用:value中不能直接绑定props中的属性,以免出现数据紊乱,故需要在data中重新注册数据,然后对data中的数据进行修改
const cpn = {
template: '#cnp',
// 避免直接修改props中的值,直接修改可能会导致数据紊乱出错
data() {
return {
dnumber1:this.num1,
dnumber2:this.num2
}
},
props:{
num1:Number,
num2:Number
},
}
然后子组件中自定义事件,发射给父组件,这里我们把v-model拆开也是为了方便自定义事件( v-model 等于 :value=”+ @input=’ =event.target.value’ 定义为一个新事件
methods:{
num1Input(event){
this.dnumber1 = event.target.value;
// 发送事件
this.$emit('num1change',this.dnumber1);
},
num2Input(event){
this.dnumber2 = event.target.value;
// 发送事件
this.$emit('num2change',this.dnumber2);
}
}
<template id="cnp">
<div>
<h2>props:{{dnumber1}}</h2>
<h2>data:{{num1}}</h2>
<!-- v-model 等于 :value=''+ @input=' =$event.target.value'-->
<!-- <input type="text" :value='dnumber1' @input ='dnumber1=$event.target.value'> -->
<input type="text" :value='dnumber1' @input ='num1Input'>
<h2>props:{{dnumber2}}</h2>
<h2>data:{{num2}}</h2>
<input type="text" :value='dnumber2' @input ='num2Input'>
</div>
</template>
发射事件后,需要在父组件中监听,并在父组件中声明做出反应,将dnumber的值付给number,同时number的值就是num的值,故最后实现number和num的值相同并实现实时绑定。
<div id="app">
<cpn
:num1='number1'
:num2='number2'
//监听事件
@num1change ='num1change'
@num2change ='num2change'
>
</cpn>
</div>
const app = new Vue({
el: "#app",
data: {
number1:1,
number2:0
},
components: {
cpn
},
methods:{
num1change(value){
//传入的value的类型默认为字符串,通过parsInt()可以将value的类型转化为int类型
this.number1 = parseInt(value),
//this.number2 = parseInt(value)/10
},
num2change(value){
this.number2 = parseInt(value),
//this.number1 = parseInt(value)*10
}
}
})
当然了,我们还可以使用watch来简化整个过程,我们回到将v-model拆开的部门。如果我们还是想要使用v-model的话,可以使用watch属性来对dnumber进行监听
const cpn = {
template: '#cnp',
// 避免直接修改props中的值,直接修改可能会导致数据紊乱出错
data() {
return {
dnumber1:this.num1,
dnumber2:this.num2
}
},
props:{
num1:Number,
num2:Number
},
watch:{
// 检测到dnumber发生变化后就触发事件
dnumber1(newValue){
this.$emit('num1change',this.dnumber1);
},
dnumber2(newValue){
this.$emit('num1change',this.dnumber2);
}
}
其余操作相同。