当前位置: 首页 > article >正文

第二十三章 Vue组件通信之非父子组件通信

目录

一、引言

1.1. event bus 事件总线

1.1.1. 实现步骤

1.2. provide & inject

1.2.1. 实现步骤 

二、event bus事件总线完整代码

2.1. 工程结构图 

​2.2. main.js

2.3. App.vue

2.4. EventBus.js

2.5. BaseC.vue

2.6. BaseB.vue

2.7. BaseA.vue

三、provide & inject

3.1. 工程结构图

3.2. main.js

3.3. App.vue

3.4. GrandSon.vue

3.5. SonA.vue

3.6. SonB.vue


一、引言

前面几个章节我们重点讲解了在Vue中组件的关系类别及父子组件的通信解决方案,本章内容将详细讲解关于非父子组件间的通信解决方案。那么非父子组件的通信我们分为两种:

1.1. event bus 事件总线

作用:非父子组件之间,进行简易消息传递。(复杂场景 → Vuex)

1.1.1. 实现步骤

1. 创建一个都能访问到的事件总线 (空 Vue 实例) → 在utils包下创建EventBus.js

2. A 组件(接收方),监听 Bus 实例的事件

3. B 组件(发送方),触发 Bus 实例的事件

1.2. provide & inject

作用:跨层级共享数据

注:在使用跨层级进行父组件和子孙组件进行共享数据时,能够进行简单数据类型(非响应式)及复杂数据类型(响应式)的共享,但是实际使用过程中,我们建议使用复杂类型来做数据共享,因为该类型的数据是响应式的,因此其他组件在获取使用时能够直接生效。

1.2.1. 实现步骤 

1. 父组件 provide 提供数据

2. 子/孙组件 inject 取值使用

二、event bus事件总线完整代码

2.1. 工程结构图 

2.2. main.js

import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')

2.3. App.vue

<template>
  <div class="app">
    <BaseA></BaseA>
    <BaseB></BaseB>
    <BaseC></BaseC>
  </div>
</template>

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

<style>

</style>

2.4. EventBus.js

import Vue from 'vue'

const Bus  =  new Vue()

export default Bus

2.5. BaseC.vue

<template>
  <div class="base-c">
    我是C组件(接受方)
    <p>{{msg}}</p>  
  </div>
</template>

<script>
import Bus from '../utils/EventBus'
export default {
  data() {
    return {
      msg: '',
    }
  },
  created() {
    Bus.$on('sendMsg', (msg) => {
      // console.log(msg)
      this.msg = msg
    })
  },
}
</script>

<style scoped>
.base-c {
  width: 200px;
  height: 200px;
  border: 3px solid #000;
  border-radius: 3px;
  margin: 10px;
}
</style>

2.6. BaseB.vue

<template>
  <div class="base-b">
    <div>我是B组件(发布方)</div>
    <button @click="sendMsgFn">发送消息</button>
  </div>
</template>

<script>
import Bus from '../utils/EventBus'
export default {
  methods: {
    sendMsgFn() {
      Bus.$emit('sendMsg', '今天天气不错,适合旅游')
    },
  },
}
</script>

<style scoped>
.base-b {
  width: 200px;
  height: 200px;
  border: 3px solid #000;
  border-radius: 3px;
  margin: 10px;
}
</style>

2.7. BaseA.vue

<template>
  <div class="base-a">
    我是A组件(接受方)
    <p>{{msg}}</p>  
  </div>
</template>

<script>
import Bus from '../utils/EventBus'
export default {
  data() {
    return {
      msg: '',
    }
  },
  created() {
    Bus.$on('sendMsg', (msg) => {
      // console.log(msg)
      this.msg = msg
    })
  },
}
</script>

<style scoped>
.base-a {
  width: 200px;
  height: 200px;
  border: 3px solid #000;
  border-radius: 3px;
  margin: 10px;
}
</style>

三、provide & inject

3.1. 工程结构图

3.2. main.js

import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')

3.3. App.vue

<template>
  <div class="app">
    我是APP组件
    <button @click="change">修改数据</button>
    <SonA></SonA>
    <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: 'pink',
      userInfo: {
        name: 'zs',
        age: 18,
      },
    }
  },
  methods: {
    change() {
      this.color = 'red'
      this.userInfo.name = 'ls'
    },
  },
  components: {
    SonA,
    SonB,
  },
}
</script>

<style>
.app {
  border: 3px solid #000;
  border-radius: 6px;
  margin: 10px;
}
</style>

3.4. GrandSon.vue

<template>
  <div class="grandSon">
    我是GrandSon
    {{ color }} -{{ userInfo.name }} -{{ userInfo.age }}
  </div>
</template>

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

<style>
.grandSon {
  border: 3px solid #000;
  border-radius: 6px;
  margin: 10px;
  height: 100px;
}
</style>

3.5. SonA.vue

<template>
  <div class="SonA">我是SonA组件
    <GrandSon></GrandSon>
  </div>
</template>

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

<style>
.SonA {
  border: 3px solid #000;
  border-radius: 6px;
  margin: 10px;
  height: 200px;
}
</style>

3.6. SonB.vue

<template>
  <div class="SonB">
    我是SonB组件
  </div>
</template>

<script>
export default {

}
</script>

<style>
.SonB {
  border: 3px solid #000;
  border-radius: 6px;
  margin: 10px;
  height: 200px;
}
</style>

http://www.kler.cn/a/372748.html

相关文章:

  • 智慧小区:科技之光点亮幸福家园
  • zabbix 6.0 监控clickhouse(单机)
  • 研究轮腿运动学方案的看法
  • 沈阳乐晟睿浩科技有限公司抖音小店运营创新
  • 极狐GitLab 签约新大陆自动识别,以质量和安全让智能识别更精准
  • 正则表达式:强大的文本匹配与处理工具
  • 【Linux】网络编程:初识协议,序列化与反序列化——基于json串实现,网络通信计算器中简单协议的实现、手写序列化与反序列化
  • 【Web前端】JavaScript 对象原型与继承机制
  • 「C/C++」C++ 三大特性 之 类和对象
  • 版本管理工具切换 | svn切换到gitlab | gitblit 迁移到 gitlab
  • STL——list的介绍和使用
  • 微信小程序-全局数据共享/页面间通信
  • unity :Error building Player: Incompatible color space with graphics API
  • k8s Ingress 七层负载
  • 迪杰斯特拉算法(Dijkstra‘s Algorithm
  • 路由参数与请求方式
  • 理解环境变量与Shell编程:Linux开发的基础
  • 将你的 Kibana Dev Console 请求导出到 Python 和 JavaScript 代码
  • GB/T 28046.2-2019 道路车辆 电气及电子设备的环境条件和试验 第2部分:电气负荷(4)
  • 如何写好prompt以及评测prompt的好坏
  • 14.社团管理系统(基于springboot和vue)
  • 力扣hot100-->递归/回溯
  • 10.Three.js射线拾取,实现点击选中场景中的物体
  • 【人工智能】重塑未来生活与工作的引擎
  • 鸿蒙原生应用开发及部署:首选华为云,开启HarmonyOS NEXT App新纪元
  • 【每日C/C++问题】