vue中的父组件传递数据给子组件、子组件传递数据给父组件
1、父组件传递数据给子组件
中心思想:父组件向子组件传值,需要通过props
vue中的父组件传递数据给子组件、子组件传递数据给父组件
1、父组件传递数据给子组件
中心思想:父组件向子组件传值,需要通过props
1.1 父传子数组
1 <!doctype html> 2 <html lang="en"> 3 4 <head> 5 <meta charset="UTF-8"> 6 <meta name="viewport" 7 content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> 8 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 9 <title>Document</title> 10 <script src="../helloVue/js/vue.js"></script> 11 </head> 12 13 <body> 14 <div id="app"> 15 <!-- 父组件向子组件传值,需要通过props --> 16 <cpn :cmessage="message" :cmovies="movies"></cpn> 17 </div> 18 19 <template id="cpn"> 20 <div> 21 <h1>{{cmessage}}</h1> 22 <ul> 23 <li v-for="movie in cmovies">{{movie}}</li> 24 </ul> 25 </div> 26 </template> 27 28 <script> 29 const cpn = { 30 // 子组件 31 template: '#cpn', 32 data() { 33 return { 34 title: 'VUE' 35 } 36 }, 37 props:['cmessage','cmovies'] 38 } 39 40 var app = new Vue({ 41 el: '#app', 42 data: { 43 message:'语文', 44 movies:['姜子牙','西游记','大话西游'] 45 }, 46 methods: { 47 }, 48 components: { 49 cpn 50 } 51 }) 52 53 </script> 54 </body> 55 </html>
1.2 父传子对象
1 <!doctype html> 2 <html lang="en"> 3 4 <head> 5 <meta charset="UTF-8"> 6 <meta name="viewport" 7 content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> 8 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 9 <title>Document</title> 10 <script src="../helloVue/js/vue.js"></script> 11 </head> 12 13 <body> 14 <div id="app"> 15 <!-- 父组件向子组件传值,需要通过props --> 16 <cpn :cmessage="message" :cmovies="movies"></cpn> 17 </div> 18 19 <template id="cpn"> 20 <div> 21 <h1>{{cmessage}}</h1> 22 <ul> 23 <li v-for="movie in cmovies">{{movie}}</li> 24 </ul> 25 </div> 26 </template> 27 28 <script> 29 const cpn = { 30 // 子组件 31 template: '#cpn', 32 data() { 33 return {} 34 }, 35 props: { 36 // 不能使用驼峰命名法 37 cmessage: { 38 type:String, 39 default:'111', 40 required:true 41 }, 42 cmovies:{ 43 type:Array, 44 default:[] 45 } 46 } 47 } 48 49 var app = new Vue({ 50 el: '#app', 51 data: { 52 message:'语文', 53 movies:['姜子牙','西游记','大话西游'] 54 }, 55 methods: { 56 }, 57 components: { 58 cpn 59 } 60 }) 61 62 </script> 63 </body> 64 65 </html>
2、子组件传递数据给父组件
当子组件需要向父组件传递数据的时候,就需要用到自定义事件来完成,v-on不仅可以用来监听dom事件,也可以用来监听组件间的自定义事件
流程:
在子组件中,用$emit()来触发事件
在父组件中,通过v-on来监听子组件事件
步骤:
1.$emit()通过自定义事件,并发射数据
2.在所挂载的组件中使用所发射的自定义事件
3.在父级方法中使用自定义事件中所触发的方法获取数据
1 <!doctype html> 2 <html lang="en"> 3 4 <head> 5 <meta charset="UTF-8"> 6 <meta name="viewport" 7 content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> 8 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 9 <title>Document</title> 10 <script src="../helloVue/js/vue.js"></script> 11 </head> 12 13 <body> 14 <div id="app"> 15 <!-- 2、在所挂载的组件中使用所发射的自定义事件 --> 16 <cpn @item-click="cpnClick"></cpn> 17 </div> 18 19 <template id="cpn"> 20 <div> 21 <button v-for="item in goods" @click = "btnClick(item)">{{item.name}}</button> 22 </div> 23 </template> 24 25 <script> 26 const cpn = { 27 // 子组件 28 template: '#cpn', 29 data() { 30 return { 31 goods:[ 32 { id: 1, name: '牛奶' }, 33 { id: 2, name: '零食' }, 34 { id: 3, name: '大米' }, 35 { id: 4, name: '水果' }, 36 ] 37 } 38 }, 39 methods: { 40 // 1.$emit()通过自定义事件item-click名称,发射数据item 41 btnClick(item){ 42 this.$emit('item-click',item) 43 } 44 } 45 46 } 47 48 var app = new Vue({ 49 el: '#app', 50 data: { 51 message: '好困困困困困' 52 }, 53 methods: { 54 // 3.在父级方法中使用自定义事件中所触发的方法获取数据 55 cpnClick(item){ 56 console.log(item) 57 } 58 }, 59 components: { 60 cpn 61 } 62 }) 63 64 </script> 65 </body> 66 67 </html>
父传子、子传父案例
需求:
将父组件的数组传递给子组件,再在子组件中修改数据后再传递给父组件
思路
1.通过在子组件中使用props将父组件的数据传递过来
2.在子组件中修改传递过来的数据,但不能利用绑定来直接修改props中的数据
解决办法:通过在子组件的data中声明一个中间者,修改中间者
3.将子组件所修改的中间者通过$emit()发送数据给父组件
1 <!doctype html> 2 <html lang="en"> 3 4 <head> 5 <meta charset="UTF-8"> 6 <meta name="viewport" 7 content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> 8 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 9 <title>Document</title> 10 <script src="../helloVue/js/vue.js"></script> 11 </head> 12 13 <body> 14 <div id="app"> 15 <h2>父组件num1: {{num1}}</h2> 16 <h2>父组件num2: {{num2}}</h2> 17 <cpn :number1="num1" :number2="num2" @num1change=number1change @num2change=number2change></cpn> 18 </div> 19 20 21 <template id="cpn"> 22 <div> 23 <p>{{number1}}</p> 24 <input type="text" @input=num1Change :value="number1"> 25 <p>{{number2}}</p> 26 <input type="text" @input=num2Change :value="number2"> 27 </div> 28 </template> 29 30 <script> 31 var cpn = { 32 template: '#cpn', 33 data() { 34 return { 35 cnum1:this.number1, 36 cnum2:this.number2 37 } 38 }, 39 props: { 40 number1:{ 41 type:Number 42 }, 43 number2: { 44 type: Number 45 } 46 }, 47 methods: { 48 num1Change(event) { 49 this.cnum1 = event.target.value*1 50 this.$emit('num1change', this.cnum1) 51 }, 52 num2Change(event) { 53 this.cnum1 = event.target.value * 1 54 this.$emit('num2change', this.cnum2) 55 } 56 } 57 } 58 59 var app = new Vue({ 60 el: '#app', 61 data: { 62 num1:1, 63 num2:2 64 }, 65 methods: { 66 number1change(value){ 67 this.num1 = value 68 }, 69 number2change(value) { 70 this.num2 = value 71 } 72 }, 73 components: { 74 cpn 75 } 76 }) 77 78 /* 79 * 父级里面有数据,子级里面没有数据 80 * 父级的data数据传入props,props传入子级data 81 * 子级data驱动input和p里的内容 82 * 子级input输入时,修改了子级的data,并且发射给父级,父级修改自身的data 83 * 父级data再次流入props 84 * */ 85 86 </script> 87 </body> 88 </html>
通过watch的父子访问案例
1 <!doctype html> 2 <html lang="en"> 3 4 <head> 5 <meta charset="UTF-8"> 6 <meta name="viewport" 7 content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> 8 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 9 <title>Document</title> 10 <script src="../helloVue/js/vue.js"></script> 11 </head> 12 13 <body> 14 <div id="app"> 15 <h2>父组件num1: {{num1}}</h2> 16 <cpn :number1="num1" :number2="num2" @num1change=number1change @num2change=number2change></cpn> 17 </div> 18 <template id="cpn"> 19 <div> 20 <p>{{number1}}</p> 21 <input type="text" v-model="cnum1"> 22 <p>{{number2}}</p> 23 <input type="text" v-model="cnum2"> 24 </div> 25 </template> 26 27 <script> 28 var cpn = { 29 template: '#cpn', 30 data() { 31 return { 32 cnum1: this.number1, 33 cnum2: this.number2 34 } 35 }, 36 props: { 37 number1: { 38 type: Number 39 }, 40 number2: { 41 type: Number 42 } 43 }, 44 watch: { 45 cnum1(newValue,oldValue) { 46 this.$emit('num1change', this.cnum1*1) 47 }, 48 cnum2(newValue) { 49 this.$emit('num2change', this.cnum2*1) 50 } 51 } 52 } 53 var app = new Vue({ 54 el: '#app', 55 data: { 56 num1: 1, 57 num2: 2 58 }, 59 methods: { 60 number1change(value) { 61 this.num1 = value 62 }, 63 number2change(value) { 64 this.num2 = value 65 } 66 }, 67 components: { 68 cpn 69 } 70 }) 71 </script> 72 </body> 73 </html>