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>

 

posted @ 2022-06-14 16:58  看一百次夜空里的深蓝  阅读(126)  评论(0编辑  收藏  举报