Vue.js入门-组件间的通信

70 阅读2分钟

方式一:_props:父组件向子组件传输数据

App向Son传输两个参数“hello“,”helloMsg”,hello参数前带有冒号,这时候App传的是msg变量的值,而helloMsg传的则是字符串“msg”。

<template>
    <Son :hello="msg" helloMsg="msg" @click.native=""/>
</template>

<script>
import Son from './components/Son.vue'
export default {  
  name: 'App',  
  components: {  
    Son  
  },  
  data(){  
    return {  
      msg: 'App'  
    }  
  },
}
</script>
export default {  
  name: 'Son',
  // 方式一
  //props: ['hello', 'helloMsg'],
  // 方式二
  props: {  
    hello : {  
      type: String,  // 接收的变量类型,如果App传输的变量不是在此声明的类型,则会报错
      default: 'LearnAxios',  // 如果App没有传输此变量时,设置默认值
    },
    helloMsg: {type: String}
  }
}

方式二:自定义事件:子组件向父组件传输数据

在子组件上声明自定义事件,然后子组件在需要传输数据到父组件的时候,触发这个自定义事件,而父组件可通过函数接收回传值。此方式不需要去解绑自定义事件,而在以下两种方式则需要。

<template>
    <Son @sendData="receiveData" ref="son" />
</template>

<script>
import Son from './components/Son.vue'
export default {  
  name: 'App',  
  components: {  
    Son  
  },  
  methods: {  
    receiveData(value) {  
      console.log('App接收到数据:', value)  
    }
  },
}
</script>
export default {  
  name: 'Son',
  methods: {
    // 在需要的时候,调用此方法触发自定义事件,然后自定义组件会触发绑定App相关函数
    clickToSendData() {
      this.$emit('sendData', 'hhh')
    }
  }
}

方式三:全局事件总线($bus) 一般使用这个

在main.js注册全局事件总线(在beforeCreate时引入)

new Vue({  
  render: h => h(App),  
  
  beforeCreate(){  
    // 不一定要叫$bus,这个名字是自定义的
    Vue.prototype.$bus = this  
  }  
}).$mount('#app')

在需要接收数据的cmp的mounted钩子函数接收数据。因为$bus是全局的,所以在Son定义的自定义事件与其他cmp定义的自定义事件名称重复的话就会发生冲突,在组件销毁前,应该要去解绑这个自定义事件。

mounted() {  
  // 如果不小心把自定义事件名称与原生的事件重名了,想让原生事件生效在事件名称加".native",如:@click.native=""
  this.$bus.$on('sendData1', (res) => {  
    console.log('App bus收到数据:', res)  
  })  
  // 或
  this.$bus.$on('sendData1', this.receiveData)  
  
  // 如需延时挂载
  setTimeout(()=>{
    this.$refs.son.$on('sendData1', this.receiveData)
  }, 3000)
}

而发送数据的子组件在原有的this.$emit改为this.$bus.$emit即可。

export default {  
  name: 'Son',
  methods: {
    // 在需要的时候,调用此方法触发自定义事件,然后自定义组件会触发绑定App相关函数
    clickToSendData() {
      this.$emit('sendData', 'hhh') // 方式二
      this.$bus.$emit('sendData1', 'xxx')  // 触发自定义事件
    },
    deadEvent() {
      // 销毁自定义事件,三种方式
      this.$off('sendData')
      this.$off(['sendData1'])
      this.$off()
    }
  }
}

方式四:消息订阅与发布(pubsub.js / mitt)

安装模块pubsub.js

npm i pubsub-js

在需要接收数据的cmp订阅消息

<script>  
import PubSub from 'pubsub-js'

export default {  
  name: 'App',  
  components: {  
    Son  
  }, 
  mounted() {  
    // 订阅消息。接收的参数第一个是这个消息名称,第二个才是消息内容
    PubSub.subscribe('hello', (eventName, resp)=>{  
      console.log('subscribe ===> ', resp)  
    })  
  },  
  beforeDestroy() {  
    // 取消订阅  
    PubSub.unsubscribe('hello')  
  }  
}
</script>

在发送数据的cmp发布消息

<script>  
import PubSub from 'pubsub-js'

export default {  
  name: 'Son',
  methods: {
    clickToSendData() {
      PubSub.publish('hello', "what's up")
    }
  }
}
</script>

参考链接:pubsub-jsmitt