最近在看父子传值和双向绑定,记录一下
定义父组件和子组件
子组件:
const cpn={
template:'#cpn',
props:{
number1: Number,
number2: Number
},
methods: {
changenub1(event){
this.dnumber1 = event.target.value //修改dnumber1
this.$emit('num1change',this.dnumber1)
},
changenub2(event){
this.dnumber2 = event.target.value
this.$emit('num2change',this.dnumber2)
}
},
data(){
return{
dnumber1:this.number1,
dnumber2:this.number2
}
}
}
父组件:
const app = new Vue({
el:'#app',
data:{
num1:1,
num2:0
},
methods:{
num1change(value){
this.num1 = parseInt(value)
},
num2change(value){
this.num2 = parseInt(value)
}
},
components:{
cpn
}
})
HTML
<div id="app">
{{num1}}===={{num2}}
<cpn :number1="num1" :number2="num2" @num1change="num1change" @num2change="num2change"></cpn>
<img src="../image/1.png" alt="">
</div>
<template id="cpn">
<div>
<h2>props: {{number1}}</h2>
<h2>data: {{dnumber1}}</h2>
<input type="text" :value="dnumber1" @input="changenub1">
<h2>props: {{number2}}</h2>
<h2>data: {{dnumber2}} {{typeof dnumber2}}</h2>
<input type="text" :value="dnumber2" @input="changenub2">
</div>
</template>
现在我们将父组件中的num1 和num2传递到子组件中:
这一步就是通过Props来进行传值
这个时候如果我们想通过子组件中的input动态的修改我们父主键的值应该怎么办呢?
我们应该可以想到,在子组件中将input和props进行双向绑定,输入的时候修改props的值 然后再通过子向父传递值,这样似乎是可以将父 子 input 的值都动态的绑定起来,那就让我们来试试
将changenub1的代码改为下面的样子我们就可以直接修改props中的number1并返回给父主键
changenub1(event){ this.number1 = event.target.value this.$emit('num1change',this.number1) }
但是再浏览器中运行的时候,我们会发现有这么一个 warn
他让我们避免直接更改prop,因为每当父组件重新渲染时,该值都会被覆盖。取而代之的是使用数据或计算属性。
不知道你们有没有注意到他说的是让我们不要直接更改props的值
不能直接修改,那我们就间接修改嘛!
再最上面的代码中我们用子组件中datade dnumber来进行修改,这个dnumber就像是number的一个副本,让他和我们的input和props进行绑定,然后通过dnumber把数据传给我们的父组件 这样我们就避免了直接修改posp来修改父组件。 看文字可能会不太懂 直接上图:!
箭头代表值的传递,横线代表双向绑定 这样是不是就直观的多了?
我们可以去试试输入的时候值是否都在变化了,但是再这个时候又发现了一个问题:
当我把input删完,我们会发现num1 和 props都是NaN 但是data 却是空的 讲道理他们应该是一样的啊
让我们修改成这样看看他的类型<h2>data: {{dnumber1}}{{typeof dnumber1}}</h2>
有值的时候 他是number类型
但是删除后他是一个string类型了这是啥原因呢
其实很简单 dnumber绑定的是input的value 他本来就是一个 string 所以我们再上面的代码中才会加上一个parseInt(value)
来转换它。