1.父组件向子组件传递数据:通过props
<html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <title>vue组件的使用</title> <style> body{ color:burlywood; } .header{ 100%; height: 40px; background-color: #333; line-height: 40px; text-align: center; } .aside{ 20%; height: 1200px; background-color:chocolate; float: left; } .content{ 80%; height: 1200px; background-color:crimson; float: left; } .footer{ 100%; height: 40px; background-color:darkcyan; text-align: center; line-height: 40px; clear: both; } </style> </head> <body> <div id='app'></div> <script> // 声明组件 var Vheader = { template : ` <div class='header'> 头部区域 </div> `, } var Vaside = { template : ` <div class='aside'> 侧边栏区域 </div> `, } var Vcontent = { // 6.在标签中使用props中的数据 // 通过props传递数据时,若使用了v-for,必须绑定key template : ` <div class='content'> <ul> <li v-for='(title,index) in titles' :key = 'index'> <h3>{{title}}</h3> </li> </ul> </div> `, // 5.通过props从父组件中拿到数据 props:['titles'], } var Vfooter = { template : ` <div class='footer'> 脚部内容 </div> `, } var Vmain = { // 4.在当前组件中绑定属性,将从父组件中拿到的数据传入自己的子组件中 template : ` <div class='main'> <Vheader/> <Vaside/> <Vcontent :titles = 'titles'/> <Vfooter/> </div> `, components:{ Vheader, Vaside, Vcontent, Vfooter, }, // 3.通过props从当前组件的父组件拿数据 props:['titles'], } new Vue({ el:'#app', // 1.在data中声明数据 data(){ return{ titles:['标题一','标题二','标题三','标题四'], } }, // 使用组件 // 2.在父组件中绑定属性,将data中的数据传到子组件中 template:` <Vmain :titles = 'titles'></Vmain> `, // Vue实例化对象的template中需要一个包裹所有元素的根元素,否则会报错 // 挂载组件 components:{ Vmain, } }) </script> </body> </html>
2.子组件向父组件传递数据:通过自定义事件
<html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <title>vue组件的使用</title> <style> body{ color:burlywood; } .header{ 100%; height: 40px; background-color: #333; line-height: 40px; text-align: center; } .aside{ 20%; height: 1200px; background-color:chocolate; float: left; } .content{ 80%; height: 1200px; background-color:crimson; float: left; } .footer{ 100%; height: 40px; background-color:darkcyan; text-align: center; line-height: 40px; clear: both; } </style> </head> <body> <div id='app'></div> <script> var Vheader = { template : ` <div class='header'> 头部区域 </div> `, } var Vaside = { // 1.在html标签中绑定原生js事件 template : ` <div class='aside'> 工具 <br/> <button @click='addFontSize'>字体+</button> </div> `, methods:{ // 2.在methods中声明所使用的方法 addFontSize(){ // 3.调用内建的this.$emit()方法触发父组件的自定义事件 // this.$emit()方法,可传入两个参数,第一个参数时事件名称,第二个参数是传入事件的参数 this.$emit('addFontSize'); } }, } var Vcontent = { template : ` <div class='content'> <ul> <li v-for='(title,index) in titles' :key = 'index'> <h3>{{title}}</h3> </li> </ul> </div> `, props:['titles'], } var Vfooter = { template : ` <div class='footer'> 脚部内容 </div> `, } var Vmain = { // 5.在template中绑定自定义事件传给子组件 template : ` <div class='main' :style='{fontSize:fontSize+"px"}'> <Vheader/> <Vaside @addFontSize='addFontSize'/> <Vcontent :titles = 'titles'/> <Vfooter/> </div> `, components:{ Vheader, Vaside, Vcontent, Vfooter, }, // 注意:data必须是一个函数 data(){ return { fontSize:16, } }, methods:{ // 4.在methods中自定义事件 addFontSize(){ this.fontSize += 1; } }, props:['titles'], } new Vue({ el:'#app', data(){ return{ titles:['标题一','标题二','标题三','标题四'], } }, template:` <Vmain :titles = 'titles'></Vmain> `, components:{ Vmain, } }) </script> </body> </html>
3.平行组件通信:创建bus实例,通过bus挂载($on)和调用($emit)事件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <div id="app"> <App></App> </div> <script src="./vue.js"></script> <script> //1.实例化一个bus对象 const bus = new Vue(); // 中央事件总线 bus Vue.component('B', { data() { return { count: 0 } }, template: ` <div>{{count}}</div> `, created(){ // 2. $on 绑定事件 bus.$on('add',(n)=>{ this.count+=n; }) } }) Vue.component('A', { template: ` <div> <button @click='handleClick'>加入购物车</button> </div> `, methods:{ handleClick(){ // 3.触发绑定的函数 // $emit 触发事件 bus.$emit('add',1); } } }) const App = { template: ` <div> <A></A> <B></B> </div> `, } new Vue({ el: '#app', components: { App } }) </script> </body> </html>
4.嵌套组件通信,父组件 provide来提供变量,然后再子组件中通过inject来注入变量.无论组件嵌套多深
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <div id="app"> <App></App> </div> <script src="./vue.js"></script> <script> Vue.component('B', { data() { return { count: 0 } }, inject:['msg'], created(){ console.log(this.msg); }, template: ` <div> {{msg}} </div> `, }) Vue.component('A', { created(){ console.log(this); }, template: ` <div> <B></B> </div> ` }) const App = { data() { return { title:"老爹" } }, provide(){ return { msg:"老爹的数据" } }, template: ` <div> <A></A> </div> `, } new Vue({ el: '#app', components: { App } }) </script> </body> </html>
5.$parrent $children