vue 组件通信

116 阅读1分钟

props/$emit

//子组件
<template>
  <div class="child">
    <input type="text" v-model="message" @keyup="send" />
    <p>收到来自父组件的消息:{{ messageFromParent }}</p>
  </div>
</template>
<script>
export default {
  name'Child',
  props: ['messageFromParent'],  // 通过props接收父组件传过来的消息
  data() {
    return {
      message'',
    }
  },
  methods: {
    send() {
      // 通过$emit触发on-receive事件,调用父组件中receive回调,并将this.message作为参数
      this.$emit('on-receive'this.message)  
    },
  },
}
</script>

//父组件
<template>
  <div class="parent">
    <input type="text" v-model="message" />
    <p>收到来自子组件的消息:{{ messageFromChild }}</p>
    <Child :messageFromParent="message" @on-receive="receive" />
  </div>
</template>
<script>
import Child from './child'
export default {
  name'Parent',
  data() {
    return {
      message''// 传递给子组件的消息
      messageFromChild'',
    }
  },
  components: {
    Child,
  },
  methods: {
    receive(msg) {
      // 接受子组件的信息,并将其赋值给messageFromChild
      this.messageFromChild = msg
    },
  },
}
</script>

v-slot

// 子组件
<template>
  <div class="child">
    <h4>this is child component</h4>
    <!--展示父组件通过插槽传递的{{message}}-->
    <slot name="child"></slot>  
  </div>
</template>

//父组件
<template>
  <div class="parent">
    <h3>this is parent component</h3>
    <input type="text" v-model="message" />
    <Child>
      <template v-slot:child>
        {{ message }}  <!--插槽要展示的内容-->
      </template>
    </Child>
  </div>
</template>
<script>
import Child from './child'
export default {
  name'Parent',
  data() {
    return {
      message'',
    }
  },
  components: {
    Child,
  },
}
</script>

refs/parent/children/root

// 子组件
<template>
  <div class="child">
    <h4>this is child component</h4>
    <input type="text" v-model="message" />
    <!--展示父组件实例的message-->
    <p>收到来自父组件的消息:{{ $parent.message }}</p>  
  </div>
</template>
<script>
export default {
  name'Child1',
  data() {
    return {
      // 父组件通过this.$children可以获取子组件实例的message
      message'',   
    }
  },
}
</script>

// 父组件
<template>
  <div class="parent">
    <h3>this is parent component</h3>
    <input type="text" v-model="message" />
    <!--展示子组件实例的message-->
    <p>收到来自子组件的消息:{{ child1.message }}</p> 
    <Child />
  </div>
</template>
<script>
import Child from './child'
export default {
  name'Parent',
  data() {
    return {
      message'',
      child1: {},
    }
  },
  components: {
    Child,
  },
  mounted() {
    this.child1 = this.$children.find((child) => {
      //通过options.name获取对应name的child实例
      return child.$options.name === 'Child1'  
    })
  },
}
</script>

eventBus

//eventBus又称事件总线,通过注册一个新的Vue实例,通过调用这个实例的和on等来监听和触发这个实例的事件,通过传入参数从而实现组件的全局通信。原理其实比较简单,就是使用订阅-发布模式.实现emit和on两个方法即可.全局监听和响应。
export default class Bus {
  constructor() {
    this.callbacks = {}
  }
  $on(event, fn) {
    this.callbacks[event] = this.callbacks[event] || []
    this.callbacks[event].push(fn)
  }\
  $emit(event, args) {
    this.callbacks[event].forEach((fn) => {
      fn(args)
    })
  }
}
// 在main.js中引入以下
Vue.prototype.$bus = new Bus()

// 当项目过大时,bus.js使用时通过import引入
import Vue from 'vue'
export const Bus = new Vue()

//使用时
mounted() {
    this.$bus.$on('sendMessage'(obj) => { 
      // 通过eventBus监听sendMessage事件
      const { sender, message } = obj
      this.sender = sender
      this.messageFromBus = message
    })
  },
  methods: {
    sendMessage() {
      this.$bus.$emit('sendMessage', { 
        // 通过eventBus触发sendMessage事件
        senderthis.$options.name,
        messagethis.message,
      })
    },
  },