vue-组件(父子组件及组件间数据传递)
一、父子组件
- 在一个组件内部定义另一个组件,称为父子组件。
- 子组件只能在父组件内部使用。
- 默认情况下,子组件不能访问父组件的数据,每个组件实例作用域都是独立的。
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>父子组件及组件间数据传递</title> 6 <!--引入vue--> 7 <script src="../js/vue.js"></script> 8 </head> 9 <body> 10 11 <div id="hello"> 12 <father></father> 13 </div> 14 15 <template id="king"> 16 <div> 17 <h3>我是父组件father</h3> 18 <h3>父组件访问自己的数据:{{msg}},{{name}},{{age}},{{user.id}},{{user.username}}</h3> 19 <!-- 子组件只能在父组件内部使用 --> 20 <son></son> 21 </div> 22 </template> 23 24 <template id="kingson"> 25 <div> 26 <h3>我是子组件son</h3> 27 <!-- 子组件不能访问父组件的数据 --> 28 <!-- <h3>子组件访问父组件的数据:{{msg}},{{name}},{{age}},{{user.id}},{{user.username}}</h3> --> 29 </div> 30 </template> 31 32 33 <script> 34 //vue实例 35 let vm = new Vue({ //vm其实也是一个组件,是根组件Root 36 el:'#hello', 37 //自定义局部组件 38 components:{ 39 'father':{ //父组件 40 data(){ 41 return { 42 msg:'欢迎来到王者荣耀', 43 name:'腾讯', 44 age:23, 45 user:{ 46 id:9688, 47 username:'马化腾' 48 } 49 } 50 }, 51 template:'#king', 52 components:{ 53 'son':{ //子组件 54 template:'#kingson' 55 }, 56 }, 57 }, 58 59 } 60 }); 61 </script> 62 </body> 63 </html>
二、组件间的数据传递(通信)
2.1 子组件访问父组件的数据
- a) 在父组件中调用子组件时,绑定想要获取的父组件中的数据。
- b) 在子组件内部,使用props选项声明获取的数据(即接收来自父组件的数据)。
注:组件中的数据共有三种形式:data、props、computed
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>父子组件及组件间数据传递</title> 6 <!--引入vue--> 7 <script src="../js/vue.js"></script> 8 </head> 9 <body> 10 11 <div id="hello"> 12 <father></father> 13 </div> 14 15 <template id="king"> 16 <div> 17 <h3>我是父组件father</h3> 18 <h3>父组件访问自己的数据:{{msg}},{{name}},{{age}},{{user.id}},{{user.username}}</h3> 19 <!-- 子组件只能在父组件内部使用 自定义绑定属性把父组件数据传递给子组件--> 20 <son :message='msg' :name='name' :age='age' :user='user'></son> 21 </div> 22 </template> 23 24 <template id="kingson"> 25 <div> 26 <h3>我是子组件son</h3> 27 <!-- 默认情况下,子组件不能访问父组件的数据(错误写法) --> 28 <!-- <h3>子组件访问父组件的数据:{{msg}},{{name}},{{age}},{{user.id}},{{user.username}}</h3> --> 29 30 <!-- 子组件访问父组件中的数据 (正确写法)--> 31 <h3>子组件访问父组件的数据:{{message}},{{name}},{{age}},{{user.id}},{{user.username}}</h3> 32 </div> 33 </template> 34 35 36 <script> 37 //vue实例 38 let vm = new Vue({ //vm其实也是一个组件,是根组件Root 39 el:'#hello', 40 //自定义局部组件 41 components:{ 42 'father':{ //父组件 43 data(){ 44 return { 45 msg:'欢迎来到王者荣耀', 46 name:'腾讯', 47 age:23, 48 user:{ 49 id:9688, 50 username:'马化腾' 51 } 52 } 53 }, 54 template:'#king', 55 components:{ 56 'son':{ //子组件 57 template:'#kingson', 58 59 //子组件通过props选项接收父组件传递过来的数据 60 //props:['message','name','age','user'] //props使用简单的数组形式 61 62 //props也可以是对象,允许设置高级配置,如类型判断、数据校验、设置默认值等 63 props:{ 64 message:String, 65 name:{ 66 type:String, //必须为字符串类型 67 required:true //必传 68 }, 69 age:{ 70 type:Number, //必须为数字类型 71 default:20, //默认值为20 72 validator:function(value){ //校验传递过来的值必须大于0 73 return value>=0; 74 } 75 }, 76 user:{ 77 type:Object, 78 default:function(){ 79 return { //对象或数组的默认值不能直接指定,必须使用函数的形式返回 80 id:1001, 81 username:'马云' 82 } 83 } 84 }, 85 86 } 87 88 }, 89 }, 90 }, 91 92 } 93 }); 94 </script> 95 </body> 96 </html>
2.2 父组件访问子组件的数据
- a) 在子组件中使用vm.$emit(自定义的事件名,要发送的数据)触发一个事件。
- b) 在父组件在使用子组件的地方监听子组件触发的事件(e-son),并在父组件中定义方法(getData)获取子组件传递过来的数据
总结:子组件通过events给父组件发送消息,实际上就是子组件把自己的数据发送给父组件。
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>父子组件及组件间数据传递</title> 6 <!--引入vue--> 7 <script src="../js/vue.js"></script> 8 </head> 9 <body> 10 11 <div id="hello"> 12 <father></father> 13 </div> 14 15 <template id="king"> 16 <div> 17 <h3>我是父组件father</h3> 18 <h3>父组件访问自己的数据:{{msg}},{{name}},{{age}},{{user.id}},{{user.username}}</h3> 19 <h3>父组件访问子组件的数据:{{sex}} {{height}}</h3> 20 <!-- 子组件只能在父组件内部使用 自定义绑定属性把父组件数据传递给子组件--> 21 <son :message='msg' :name='name' :age='age' :user='user' @e-son='getData'></son> 22 </div> 23 </template> 24 25 <template id="kingson"> 26 <div> 27 <h3>我是子组件son</h3> 28 <!-- 子组件访问父组件中的数据 --> 29 <h3>子组件访问父组件的数据:{{message}},{{name}},{{age}},{{user.id}},{{user.username}}</h3> 30 31 <h3>子组件访问自己的数据:{{sex}},{{height}}</h3> 32 <button @click='send'>子组件的数据向上发送给父组件</button> 33 </div> 34 </template> 35 36 37 <script> 38 //vue实例 39 let vm = new Vue({ //vm其实也是一个组件,是根组件Root 40 el:'#hello', 41 //自定义局部组件 42 components:{ 43 'father':{ //父组件 44 data(){ 45 return { 46 msg:'欢迎来到王者荣耀', 47 name:'腾讯', 48 age:23, 49 user:{ 50 id:9688, 51 username:'马化腾' 52 }, 53 //初始化变量,用于接收子组件传递过来的sex和height 54 sex:'', 55 height:'' 56 } 57 }, 58 methods:{ 59 getData(sex,height){ 60 this.sex=sex; 61 this.height=height; 62 } 63 }, 64 template:'#king', 65 components:{ 66 'son':{ //子组件 67 template:'#kingson', 68 data(){ 69 return { 70 sex:'男', 71 height:'180cm' 72 } 73 }, 74 methods:{ 75 send(){ 76 console.log(this); //此处的this表示子组件son 77 this.$emit('e-son',this.sex,this.height); //使用$emit触发一个事件,发送数据 78 } 79 }, 80 81 //子组件通过props选项接收父组件传递过来的数据 82 //props:['message','name','age','user'] //props使用简单的数组形式 83 84 //props也可以是对象,允许设置高级配置,如类型判断、数据校验、设置默认值等 85 props:{ 86 message:String, 87 name:{ 88 type:String, //必须为字符串类型 89 required:true //必传 90 }, 91 age:{ 92 type:Number, //必须为数字类型 93 default:20, //默认值为20 94 validator:function(value){ //校验传递过来的值必须大于0 95 return value>=0; 96 } 97 }, 98 user:{ 99 type:Object, 100 default:function(){ 101 return { //对象或数组的默认值不能直接指定,必须使用函数的形式返回 102 id:1001, 103 username:'马云' 104 } 105 } 106 }, 107 108 } 109 110 }, 111 }, 112 }, 113 114 } 115 }); 116 </script> 117 </body> 118 </html>