9Vue父子组件的传递方式
写个计数器组件,雏形如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="./vue.js"></script> <title>Document</title> </head> <body> <div id="app"> <counter></counter> <counter></counter> </div> </body> <script> var counter={ template:'<div>0</div>' } var vm=new Vue({ el:"#app", components:{ counter:counter } }) </script> </html>
1.可以通过属性传值
注意:“count”和“:count”的区别。
<body> <div id="app"> <!--父组件 可以通过属性向子组件传值 ,通过props接受--> <!-- <counter count="0"></counter>这种形式也可以传值,不过传的值是字符串 --> <!-- 下面这种形式传值,传递的是引号内的js表达式 ,传的是数字--> <counter :count="0"></counter> <counter :count="2"></counter> </div> </body>
var counter={ props:['count'], template:'<div>{{count}}</div>' } var vm=new Vue({ el:"#app", components:{ counter:counter } })
结果如下图:
接下来做点击就+1的效果
var counter={ props:['count'], template:'<div @click="handleClick">{{count}}</div>', methods:{ handleClick:function(){ this.count++; } } } var vm=new Vue({ el:"#app", components:{ counter:counter } })
这里直接操控count做+1动作,是可以实现需求的。但是控制台会警告:
这是因为Vue不允许在子组件中修改父组件传递的值。假如父组件传递的值是一个对象,那么子组件接收的是这个对象的引用,如果这个对象还有其他组件在使用,我们修改了这个对象的值,就会造成其他组件的值的改变,这样是不允许的。
解决方法:在子组件中用data创建一个变量,将父组件的值赋给这个变量,通过改变data中的这个变量即可。
var counter={ props:['count'], data:function(){ return { number:this.count //赋值 } }, template:'<div @click="handleClick">{{number}}</div>', methods:{ handleClick:function(){ this.number++;//使用子组件中的number,不会影响父组件的值 } } } var vm=new Vue({ el:"#app", components:{ counter:counter } })
这样计数器就可以实现了。
再加一个将两个计数器值求和的功能。
通过this.$emit设置就行
<div id="app"> <counter @inc="handleInc" :count="0"></counter> <counter @inc="handleInc" :count="0"></counter> <div>总计:{{total}}</div> </div>
var counter={ props:['count'], data:function(){ return { number:this.count } }, template:'<div @click="handleClick">{{number}}</div>', methods:{ handleClick:function(){ this.number++; //触发inc事件,并传参数1 this.$emit('inc',1) } } } var vm=new Vue({ el:"#app", data:{ total:0 }, components:{ counter:counter }, methods:{ handleInc:function(step){ //每次触发就加1 this.total+=step; } } })
完整代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="./vue.js"></script> <title>Document</title> </head> <body> <div id="app"> <!-- 监听inc事件 --> <counter @inc="handleInc" :count="0"></counter> <counter @inc="handleInc" :count="0"></counter> <div>总计:{{total}}</div> </div> </body> <script> var counter={ props:['count'], data:function(){ return { number:this.count } }, template:'<div @click="handleClick">{{number}}</div>', methods:{ handleClick:function(){ this.number++; //触发inc事件,并传参数1 this.$emit('inc',1) } } } var vm=new Vue({ el:"#app", data:{ total:0 }, components:{ counter:counter }, methods:{ handleInc:function(step){ //每次触发就加1 this.total+=step; } } }) </script> </html>