水军大提督 发表于 2024-10-31 01:49:57

第二十三章 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)
https://i-blog.csdnimg.cn/direct/56cc0a4bf43341ab87d0fae8d40ff81a.png
1.1.1. 实现步骤

1. 创建一个都能访问到的变乱总线 (空 Vue 实例) → 在utils包下创建EventBus.js
https://i-blog.csdnimg.cn/direct/82d3bc3d86d54c88a41a41ee124a53ae.png
2. A 组件(汲取方),监听 Bus 实例的变乱
https://i-blog.csdnimg.cn/direct/5ac184a3ca414c0395c105ee0c629c21.png
3. B 组件(发送方),触发 Bus 实例的变乱
https://i-blog.csdnimg.cn/direct/980862d193a540459cd37c3636e217c4.png
1.2. provide & inject

   作用:跨层级共享数据
注:在利用跨层级进行父组件和子孙组件进行共享数据时,能够进行简单数据类型(非相应式)及复杂数据类型(相应式)的共享,但是实际利用过程中,我们建议利用复杂类型来做数据共享,由于该类型的数据是相应式的,因此其他组件在获取利用时能够直接见效。
https://i-blog.csdnimg.cn/direct/6924ff36126b45e79f875474082471ea.png
1.2.1. 实现步骤 

1. 父组件 provide 提供数据
https://i-blog.csdnimg.cn/direct/ba1f272dbf3b431db16b4bfcb84604cb.png
   2. 子/孙组件 inject 取值利用
https://i-blog.csdnimg.cn/direct/ce9d8cd060604d43a189f088b2c7b82e.png
二、event bus变乱总线完整代码

2.1. 工程结构图 

https://i-blog.csdnimg.cn/direct/d145cd9e4dba4dac9bed14b5c1de6f40.png
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. 工程结构图

https://i-blog.csdnimg.cn/direct/89681276e2244af8828968f9739b0b8c.png
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>
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 第二十三章 Vue组件通信之非父子组件通信