Vue组件通信

编程 · 2023-12-04 · 201 人浏览

非父子组件通信

事件总线

非父子组件之间,进行简易消息传递,可以使用事件总线(Event Bus)。

使用步骤:

  1. 创建一个都能访问的事件总线(空Vue实例,放到utils/EventBus.js)
  2. A组件(接收方)监听Bus实例的事件(订阅消息)
  3. B组件(发送方)触发Bus实例的事件(发布消息)

src\utils\EventBus.js文件:

// 1. 创建一个都能访问的事件总线(空Vue实例)
import Vue from 'vue'

const Bus = new Vue()

export default Bus

src\components\BaseA.vue文件:

<template>
  <div>
    A组件(接收方)
    <p>{{ msg }}</p>
  </div>
</template>

<script>
import Bus from '../utils/EventBus'
export default {
  created() {
    // 2. A组件(接收方)监听Bus实例的事件(订阅消息)
    Bus.$on('sendMsg', (msg) => {
      this.msg = msg
    })
  },
  data() {
    return {
      msg: '',
    }
  },
}
</script>

src\components\BaseB.vue文件:

<template>
  <div>
    B组件(发送方)
    <button @click="clickSend">发布通知</button>
  </div>
</template>

<script>
import Bus from '../utils/EventBus'
export default {
  methods: {
    clickSend() {
      // 3. B组件(发送方)触发Bus实例的事件(发布消息)
      Bus.$emit('sendMsg', '消息内容')
    },
  },
}
</script>

src\App.vue文件:

<template>
  <div>
    <BaseA></BaseA>
    <br />
    <hr />
    <br />
    <BaseB></BaseB>
  </div>
</template>

<script>
import BaseA from './components/BaseA.vue'
import BaseB from './components/BaseB.vue'
export default {
  components: {
    BaseA,
    BaseB,
  },
}
</script>

provide和inject

作用是用来跨层级共享数据。

使用步骤:

  1. 父组件provide提供数据
  2. 子/孙组件inject取值使用

src\App.vue文件:

<template>
  <div>
    App组件
    <br />
    <SonA></SonA>
    <br />
    <SonB></SonB>
  </div>
</template>

<script>
import SonA from './components/SonA.vue'
import SonB from './components/SonB.vue'
export default {
  provide() {
    return {
      color: this.color, //简单类型(非响应式)
      userInfo: this.userInfo, //复杂类型(响应式)- 推荐
    }
  },
  data() {
    return {
      color: 'red',
      userInfo: {
        name: '张三',
        age: 18,
      },
    }
  },
  components: {
    SonA,
    SonB,
  },
}
</script>

src\components\SonA.vue文件:

<template>
  <div>
    -SonA组件
    <GrandSon></GrandSon>
  </div>
</template>

<script>
import GrandSon from './GrandSon.vue'
export default {
  components: {
    GrandSon,
  },
}
</script>

src\components\GrandSon.vue文件:

<template>
  <div>--GrandSon组件:{{ color }} - {{ userInfo.name }}</div>
</template>

<script>
export default {
  inject: ['color', 'userInfo'],
}
</script>

src\components\SonB.vue文件:

<template>
  <div>-SonB组件:{{ color }} - {{ userInfo.age }}</div>
</template>
<script>
export default {
  inject: ['color', 'userInfo'],
}
</script>
Vue
Theme Jasmine by Kent Liao