【Vue 学习】组件间通信

组件间通信

1. props 传递函数

是一种组件间消息传递的方法,适用于子 ===>>> 父

父组件:声明函数,并传递给子组件

<template>
  <MySon :sendMsg1="sendMsg1" :sendMsg2="sendMsg2"/>
</template>


<script>
import MySon from "@/components/Son.vue";

export default {
  name: "MyFather",
  components: {MySon},
  methods: {
    sendMsg1(msg1) {
      console.log(msg1)
    },
    sendMsg2(msg2) {
      console.log(msg2)
    }
  }
}
</script>

子组件:调用回调函数,并传递参数,使得父组件接收到数据

<template>
  <h1>555</h1>
</template>


<script>
export default {
  name: "MySon",
  props: ['sendMsg1', 'sendMsg2'],
  mounted() {
    this.sendMsg1(1)
    this.sendMsg2(2)
  }
}
</script>

2. 自定义事件【不推荐】

是一种组件间消息传递的方法,适用于子 ===>>> 父

组件上面也可以绑定原生的 DOM 事件,需要使用 native 修饰符,如:<Demo @click.native="show"></Demo>,此时在 Dome 组件的身上有了 clcik 事件,点击组件的时候调用回调函数 show

父组件:使用子组件,并给子组件绑定自定义事件

方法一

<template>
  <div id="root">
    <!-- @事件名称="事件回调函数的名称,实际上是函数的引用" -->
  	<MyCom 
           v-on:sendmsg1="sendmsg3"
           @sendmsg2="sendmsg1" 
           @sendmsg3.once="sendmsg2" 
    />
  </div>
</template>


<script>
import MyCom from "@/components/MyCom.vue";
export default {
  name: 'App',
  components: { MyCom },
  methods: {
    sendmsg1(data) {
      console.log(data)
    },
    sendmsg2(data) {
      console.log(data)
    }
  }
}
</script>

方法二

<script>
mounted() {
    // 可以触发多次的自定义事件
    // 	- this.$refs.demo.$on('事件名称', 事件回调函数)
    //	- 回调函数可以在 methods 中
    //	- 也可以使用匿名函数,但是必须使用箭头函数,因为 this 指向的问题
    this.$refs.demo.$on('sendmsg1', this.sendmsg1)
    this.$refs.demo.$on('sendmsg2', this.sendmsg2)
    // 只可以触发一次的自定义事件
    this.$refs.demo.$once('sendmsg2', this.sendmsg2)
}
</script>

子组件:手动触发已绑定的自定义事件,并在适当的时机解除自定义事件

<template>
  <h1>hello</h1>
</template>


<script>
export default {
  name: "MyCom",
  methods: {
    MyFun() {
      // 手动触发自定义事件
      this.$emit('sendDeleteOkTodo')
      this.$emit('sendUpdateAll', newValue)
    },
  },
  beforeDestroy() {
    // 手动解绑指定的自定义事件
    this.$off('sendDeleteOkTodo')
    // 手动解绑全部的自定义事件
	// this.$off()
  }
}
</script>

3. 全局事件总线

是一种组件间消息传递的方法,适用于任意组件 ===>>> 任意组件

本质是一个中间对象,绑定了自定义事件,然后所有的组件均可以访问到该中间对象,并且该对象必须可以使用 $on()$once()$emit() 方法去操作事件

main.js:定义全局的事件总线【定义中间对象】

//引入Vue
import Vue from 'vue'
//引入App
import App from './App.vue'
//关闭Vue的生产提示
Vue.config.productionTip = false

new Vue({
    render: h => h(App),
    beforeCreate() {
        // 给 Vue 的原型对象绑定一个中间对象,该对象是 Vue 实例 vm
        //	- Vue原型对象可以被所有的组件访问
        //	- Vue实例vm可以绑定、解绑自定义事件
        //	- $bus 是自定义的名称
        Vue.prototype.$bus = this
    }
}).$mount('#app')

父组件:绑定自定义事件【接收数据】

<template>
  <MySon/>
</template>


<script>
import MySon from "@/components/Son.vue";

export default {
  name: "MyFather",
  components: {MySon},
  mounted() {
    this.$bus.$on('sendMsg1', (data) => {
      console.log(data)
    })
    this.$bus.$on('sendMsg2', (data) => {
      console.log(data)
    })
  },
  beforeDestroy() {
    this.$off()
  }
}
</script>

子组件:手动调用自定义事件【传递数据】

<template>
  <h1>hello,world!</h1>
</template>


<script>
export default {
  name: "MySon",
  mounted() {
    this.$bus.$emit('sendMsg1', {'id': '001', 'name': 'tom'})
    this.$bus.$emit('sendMsg2', 'hello')
  }
}
</script>

4. 消息订阅与发布

是一种组件间消息传递的方法,适用于任意组件 ===>>> 任意组件【更推荐使用全局事件总线】

安装第三方库

npm i pubsub-js

父组件:引入第三方库,并订阅消息,然后再合适的位置取消订阅

<template>
  <MySon/>
</template>


<script>
// 引入第三方库
import pubsub from 'pubsub-js'
import MySon from "@/components/Son.vue";

export default {
  name: "MyFather",
  components: {MySon},
  mounted() {
    // 订阅消息,生成一个唯一 id,保持到 this 身上,以便于取消订阅
    this.id1 = pubsub.subscribe('sendMsg1', (data) => {
      console.log(data)
    })
    this.id2 = pubsub.subscribe('sendMsg2', (data) => {
      console.log(data)
    })
  },
  beforeDestory() {
    // 取消订阅
    pubsub.unsubscribe(this.id1)
    pubsub.unsubscribe(this.id2)
  }
}
</script>

子组件:发布消息,每一次的消息发布,都会生成一个唯一的消息 id,下次取消订阅时,指明该 id 即可

<template>
  <h1>hello,world!</h1>
</template>


<script>
// 引入第三方库
import pubsub from 'pubsub-js'
export default {
  name: "MySon",
  mounted() {
    // 发布消息
    pubsub.publish('sendMsg1', {id: '001',name: 'tom',age: 56})
    // 发布消息
    pubsub.publish('sendMsg2', 'hello')
  }
}
</script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

写代码的不谷

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值