Vue 自定义事件 && 组件通信
1 App.vue 2 <template> 3 <!-- 4 组件的自定义事件: 5 1.一种组件间通信的方式,使用于:子组件===>父组件 6 2.使用场景:A是父组件,B是子组件,B想给A传数据,那么就要在A中给B绑定自定义事件(事件的回调在A中) 7 3.绑定自定义事件: 8 .第一种方式,在父组件中:<Demo @custonEvent="test"/> 或 <Demo v-on:custonEvent="test"/> 9 .第二种方式,在父组件中 10 <demo ref="demo" /> 11 mounted(){this.$refs.demo.on('custonEvent', this.test)} 12 .若想让自定义事件只杯触发一次,可以使用once事件修饰符,或$once方法 13 4.触发自定义事件:this.$emit('custonEvent', 数据参数) 14 5.解绑自定义事件: this.$off('custonEvent'); 15 6.组件上也可以绑定原生DOM事件,需要使用native修饰符 16 7.注意:通过this.$refs.xxx.$on('custonEvent', 回调)绑定自定义事件时,回调要么配置在methods中,要么用箭头函数,否则this指向会出问题。
17 --> 18 <div class="app"> 19 <h1>{{msg}}</h1> 20 <!-- 通过父组件给子组件传递函数类型的props实现:子给父传递数据 --> 21 <School :getSchoolName="getSchoolName"/> 22 <!-- 通过父组件给子组件绑定一个自定义事件实现:子给父传递数据。 --> 23 <!-- <Student v-on:customEvent.once="getStudentName"/> 事件修饰符同样可以使用 --> 24 <!-- <Student v-on:customEvent="getStudentName"/> --> 25 <!-- 通过指定ref,在当前组件挂载完(mounted),的时候绑定自定义事件,这种相对比较灵活,比如:三秒后绑定事件 --> 26 <!-- 通过native事件修饰符来绑定原生事件 --> 27 <Student ref="student" @click.native="studentClick"/> 28 </div> 29 </template>
1 全局事件总线(GlobalEventBus) 2 1.一种组件间通信的方式,适用于任意组件间通信 3 2.安装全局事件总线: 4 new Vue({ 5 render: h => h(App), 6 beforeCreate(){ 7 Vue.prototype.$bus = this; 8 } 9 }).$mount('#app'); 10 3.适用事件总线: 11 a.接收数据:A组件想接收数据,则在A组件中给$bus绑定自定义事件,事件的回调留在A组件自身 12 methods(){ 13 demo(data){...} 14 } 15 ... 16 mounted() { 17 this.$bus.$on('xxx', this.demo); 18 }, 19 beforeDestroy(){ 20 this.$bus.$off('xxx'); 21 } 22 b.提供数据:this.$bus.$emit('xxx', data); 23 4.最好在beforeDestroy钩子回调中,用$off去解绑当前组件所用到的事件 24 25 26 消息订阅与发布(pubsub) 27 1.一种组件间通讯的方式,适用于任意组件间通信。 28 2.适用步骤: 29 a.安装pubsub: npm i pubsub-js 30 b.引入:import pubsub from pubsub-js 31 c.接受数据:A组件想接受数据,则在A组件中订阅消息,订阅的回调留在A组件自身 32 methods(){ 33 demo(data){....} 34 } 35 .... 36 mounted(){ 37 this.pid = pubsub.subscribe('xxx', this.demo);//订阅消息 38 } 39 beforeDestroy(){ 40 pubsub.unsubscribe(this.pid); 41 } 42 d.提供数据:pubsub.publish('xxx', data) 43 e.最好在beforeDestroy钩子中,用pubsub.unsubscribe(pid)去取消订阅
30 31 <script> 32 import School from './components/School.vue' 33 import Student from './components/Student.vue' 34 35 export default { 36 name: 'App', 37 components:{ 38 School,Student, 39 }, 40 data(){ 41 return { 42 msg: '你好啊' 43 } 44 }, 45 methods:{ 46 getSchoolName(name){ 47 console.log('App getSchoolName:', name); 48 }, 49 getStudentName(name,...a){ // ...a意思是,将其他参数都放到a上面 50 console.log('App getStudentName:', name); 51 console.log('App getStudentName:', a); 52 } 53 }, 54 mounted() { 55 // 绑定自定义事件 56 this.$refs.student.$on('customEvent', this.getStudentName); 57 58 // this.$refs.student.$onece('customEvent', this.getStudentName); 事件修饰符 59 } 60 } 61 </script> 62 63 <style> 64 .app{ 65 background-color: gray; 66 padding: 5px; 67 } 68 </style>
1 School.vue 2 <template> 3 <div class="school"> 4 <h3>学校名字:{{name}}</h3> 5 <h3>学校地址:{{address}}</h3> 6 <button @click="sendSchoolName" >把学校名传给App</button> 7 </div> 8 9 </template> 10 11 <script> 12 export default { 13 name: 'School', 14 data(){ 15 return { 16 name: 'BaiYeShu', 17 address: '深圳' 18 } 19 }, 20 props:['getSchoolName'], 21 methods:{ 22 sendSchoolName(e) { 23 this.getSchoolName(this.name); 24 } 25 } 26 27 } 28 </script> 29 30 <style scoped> 31 .school{ 32 background-color: skyblue; 33 padding: 5px; 34 } 35 </style>
1 Student.vue 2 <template> 3 <div class="student"> 4 <h3>学生姓名:{{name}}</h3> 5 <h3>学生性别:{{sex}}</h3> 6 <button @click="sendStudentName">把学生名发送给App</button> 7 <button @click="unbind">解绑自定义事件</button> 8 </div> 9 </template> 10 11 <script> 12 export default { 13 name: 'School', 14 data(){ 15 return { 16 name: '张三', 17 sex: '男', 18 } 19 }, 20 methods:{ 21 sendStudentName(){ 22 // 触发自定义事件 23 this.$emit('customEvent', this.name, 1,2,3); 24 }, 25 unbind(){ 26 this.$off('customEvent'); // 解绑指定事件 27 // this.$off(['customEvent', 'm1']); // 解绑多个事件 28 // this.$off(); // 解绑所有事件 29 } 30 } 31 } 32 </script> 33 34 <style scoped> 35 .student { 36 background-color: pink; 37 padding: 5px; 38 margin-top: 30px; 39 } 40 </style>