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

打印 上一主题 下一主题

主题 815|帖子 815|积分 2445

目次

一、弁言
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

  1. import Vue from 'vue'
  2. import App from './App.vue'
  3. Vue.config.productionTip = false
  4. new Vue({
  5.   render: h => h(App),
  6. }).$mount('#app')
复制代码
2.3. App.vue

  1. <template>
  2.   <div class="app">
  3.     <BaseA></BaseA>
  4.     <BaseB></BaseB>
  5.     <BaseC></BaseC>
  6.   </div>
  7. </template>
  8. <script>
  9. import BaseA from './components/BaseA.vue'
  10. import BaseB from './components/BaseB.vue'
  11. import BaseC from './components/BaseC.vue'
  12. export default {
  13.   components:{
  14.     BaseA,
  15.     BaseB,
  16.     BaseC
  17.   }
  18. }
  19. </script>
  20. <style>
  21. </style>
复制代码
2.4. EventBus.js

  1. import Vue from 'vue'
  2. const Bus  =  new Vue()
  3. export default Bus
复制代码
2.5. BaseC.vue

  1. <template>
  2.   <div class="base-c">
  3.     我是C组件(接受方)
  4.     <p>{{msg}}</p>  
  5.   </div>
  6. </template>
  7. <script>
  8. import Bus from '../utils/EventBus'
  9. export default {
  10.   data() {
  11.     return {
  12.       msg: '',
  13.     }
  14.   },
  15.   created() {
  16.     Bus.$on('sendMsg', (msg) => {
  17.       // console.log(msg)
  18.       this.msg = msg
  19.     })
  20.   },
  21. }
  22. </script>
  23. <style scoped>
  24. .base-c {
  25.   width: 200px;
  26.   height: 200px;
  27.   border: 3px solid #000;
  28.   border-radius: 3px;
  29.   margin: 10px;
  30. }
  31. </style>
复制代码
2.6. BaseB.vue

  1. <template>
  2.   <div class="base-b">
  3.     <div>我是B组件(发布方)</div>
  4.     <button @click="sendMsgFn">发送消息</button>
  5.   </div>
  6. </template>
  7. <script>
  8. import Bus from '../utils/EventBus'
  9. export default {
  10.   methods: {
  11.     sendMsgFn() {
  12.       Bus.$emit('sendMsg', '今天天气不错,适合旅游')
  13.     },
  14.   },
  15. }
  16. </script>
  17. <style scoped>
  18. .base-b {
  19.   width: 200px;
  20.   height: 200px;
  21.   border: 3px solid #000;
  22.   border-radius: 3px;
  23.   margin: 10px;
  24. }
  25. </style>
复制代码
2.7. BaseA.vue

  1. <template>
  2.   <div class="base-a">
  3.     我是A组件(接受方)
  4.     <p>{{msg}}</p>  
  5.   </div>
  6. </template>
  7. <script>
  8. import Bus from '../utils/EventBus'
  9. export default {
  10.   data() {
  11.     return {
  12.       msg: '',
  13.     }
  14.   },
  15.   created() {
  16.     Bus.$on('sendMsg', (msg) => {
  17.       // console.log(msg)
  18.       this.msg = msg
  19.     })
  20.   },
  21. }
  22. </script>
  23. <style scoped>
  24. .base-a {
  25.   width: 200px;
  26.   height: 200px;
  27.   border: 3px solid #000;
  28.   border-radius: 3px;
  29.   margin: 10px;
  30. }
  31. </style>
复制代码
三、provide & inject

   3.1. 工程结构图

  

  3.2. main.js

  1. import Vue from 'vue'
  2. import App from './App.vue'
  3. Vue.config.productionTip = false
  4. new Vue({
  5.   render: h => h(App),
  6. }).$mount('#app')
复制代码
3.3. App.vue

  1. <template>
  2.   <div class="app">
  3.     我是APP组件
  4.     <button @click="change">修改数据</button>
  5.     <SonA></SonA>
  6.     <SonB></SonB>
  7.   </div>
  8. </template>
  9. <script>
  10. import SonA from './components/SonA.vue'
  11. import SonB from './components/SonB.vue'
  12. export default {
  13.   provide() {
  14.     return {
  15.       // 简单类型 是非响应式的
  16.       color: this.color,
  17.       // 复杂类型 是响应式的
  18.       userInfo: this.userInfo,
  19.     }
  20.   },
  21.   data() {
  22.     return {
  23.       color: 'pink',
  24.       userInfo: {
  25.         name: 'zs',
  26.         age: 18,
  27.       },
  28.     }
  29.   },
  30.   methods: {
  31.     change() {
  32.       this.color = 'red'
  33.       this.userInfo.name = 'ls'
  34.     },
  35.   },
  36.   components: {
  37.     SonA,
  38.     SonB,
  39.   },
  40. }
  41. </script>
  42. <style>
  43. .app {
  44.   border: 3px solid #000;
  45.   border-radius: 6px;
  46.   margin: 10px;
  47. }
  48. </style>
复制代码
3.4. GrandSon.vue

  1. <template>
  2.   <div class="grandSon">
  3.     我是GrandSon
  4.     {{ color }} -{{ userInfo.name }} -{{ userInfo.age }}
  5.   </div>
  6. </template>
  7. <script>
  8. export default {
  9.   inject: ['color', 'userInfo'],
  10. }
  11. </script>
  12. <style>
  13. .grandSon {
  14.   border: 3px solid #000;
  15.   border-radius: 6px;
  16.   margin: 10px;
  17.   height: 100px;
  18. }
  19. </style>
复制代码
3.5. SonA.vue

  1. <template>
  2.   <div class="SonA">我是SonA组件
  3.     <GrandSon></GrandSon>
  4.   </div>
  5. </template>
  6. <script>
  7. import GrandSon from '../components/GrandSon.vue'
  8. export default {
  9.   components:{
  10.     GrandSon
  11.   }
  12. }
  13. </script>
  14. <style>
  15. .SonA {
  16.   border: 3px solid #000;
  17.   border-radius: 6px;
  18.   margin: 10px;
  19.   height: 200px;
  20. }
  21. </style>
复制代码
3.6. SonB.vue

  1. <template>
  2.   <div class="SonB">
  3.     我是SonB组件
  4.   </div>
  5. </template>
  6. <script>
  7. export default {
  8. }
  9. </script>
  10. <style>
  11. .SonB {
  12.   border: 3px solid #000;
  13.   border-radius: 6px;
  14.   margin: 10px;
  15.   height: 200px;
  16. }
  17. </style>
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

水军大提督

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表