Vue非父子组件之间的通信方式详解
非父子组件的通信
此篇讲解的是, 在学习状态管理之前, 非父子间通信的方案
在开发中,我们构建了组件树之后,除了父子组件之间的通信之外,还会有非父子组件之间的通信。
这里我们主要讲两种方式:
- Provide/Inject;
- 全局事件总线;
1.Provide和Inject
1.1基本使用
Provide/Inject用于非父子组件之间共享数据:
- 比如有一些深度嵌套的组件,子组件想要获取父组件的部分内容;
- 在这种情况下,如果我们仍然将props沿着组件链逐级传递下去,就会非常的麻烦;
对于这种情况下,我们可以使用 Provide 和 Inject :
- 无论层级结构有多深,父组件都可以作为其所有子组件的依赖提供者;
- 父组件有一个 provide 选项来提供数据;
- 子组件有一个 inject 选项来开始使用这些数据;
实际上,你可以将依赖注入看作是“long range props”,除了:
- 父组件不需要知道哪些子组件使用它 provide 的 property
- 子组件不需要知道 inject 的 property 来自哪里
我们开发一个下面这样的结构: 让App.vue提供一些数据给HomeContent.vue使用[外链图片转存失败,
在祖先组件中通过provide将数据传出, provide对应的是一个对象
export default { components: { Home }, // 通过provide将数据传出 provide() { return { name: this.name, age: this.age, height: this.height } } }
在后代元素中, 通过inject接收祖先传递的数据, inject对应的是一个数组
export default { inject: ["name", "age", "height"] }
1.2处理响应式数据(了解)
我们先来验证一个结果:如果我们修改了this.names的内容,那么使用length的子组件会不会是响应式的?
<template> <div class="app"> <home /> <h2>{{ name }}</h2> <button @click="btnClick">按钮</button> </div> </template> <script> import Home from './Home.vue' export default { components: { Home }, data() { return { name: "chenyq", age: 18, height: 1.88, } }, // 通过provide将数据传出 provide() { return { name: this.name, age: this.age, height: this.height } }, methods: { btnClick() { this.name = "kaisa" } }, } </script>
我们会发现对应的子组件中是没有反应的:
这是因为当我们修改了names之后,之前在provide中引入的 this.name 本身并不是响应式的;
那么怎么样可以让我们的数据变成响应式的呢?
- 非常的简单,我们可以使用响应式的一些API来完成这些功能,比如说computed函数;
- 当然,这个computed是vue3的新特性,在后面我会专门讲解,这里大家可以先直接使用一下;
import { computed } from 'vue' export default { components: { Home }, data() { return { name: "chenyq", age: 18, height: 1.88, } }, // 通过provide将数据传出 provide() { return { name: computed(() => this.name), age: this.age, height: this.name } }, methods: { btnClick() { this.name = "kaisa" } }, }
注意:我们在使用name的时候需要获取其中的value
这是因为computed返回的是一个ref对象,需要取出其中的value来使用;
<template> <div class="home-content"> <h2>名字: {{ name.value }}, 年龄: {{ age}}, 身高: {{ height}}</h2> </div> </template>
2.全局事件总线
Vue3从实例中移除了 o n 、 on、 on、off 和 $once 方法,所以我们如果希望继续使用全局事件总线,要通过第三方的库:
- Vue3官方有推荐一些库,例如 mitt 或 tiny-emitter, 这两个库虽然不再维护, 但还是可以使用的;
- 这里我们主要讲解一下 hy-event-store 的使用, 是前端大神coderwhy封装的他自己的库;
首先,我们需要先安装这个库:npm install hy-event-store
其次,我们可以封装一个工具eventbus.js:
import { HyEventBus } from "hy-event-store"; const eventBus = new HyEventBus() export default eventBus
在项目中导入后可以使用它们:
- 我们在App.vue中监听事件;
- 我们在Banner.vue中触发事件;
Banner中触发事件:
<template> <div class="home-content"> <button @click="btnClick">按钮</button> </div> </template> <script> import eventBus from './utils/event-bus' export default { methods: { btnClick() { console.log("myEvent事件被监听") // 发送事件到事件总线上 eventBus.emit("myEvent", "chenyq", 18, 1.88) } }, } </script>
App中监听事件:
<script> import eventBus from './utils/event-bus' import Home from './Home.vue' export default { components: { Home }, created() { // 监听事件总线上的事件 eventBus.on("myEvent", (name, age, height) => { console.log(name, age, height) }) }, } </script>
总结
到此这篇关于Vue非父子组件之间的通信方式的文章就介绍到这了,更多相关Vue非父子组件通信内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
Nuxt3项目中问题汇总之刷新页面useFetch无返回解决
Nuxt.js是一个基于 Vue.js 的服务端渲染应用框架,这篇文章主要给大家介绍了关于Nuxt3项目中问题汇总之刷新页面useFetch无返回解决办法的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下2024-03-03后台使用freeMarker和前端使用vue的方法及遇到的问题
这篇文章主要介绍了后台使用freeMarker和前端使用vue的方法及遇到的问题,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下2019-06-06Element-UI Table组件上添加列拖拽效果实现方法
这篇文章主要为大家详细介绍了Element-UI Table组件上添加列拖拽效果的实现方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下2018-04-04详解vue中v-for和v-if一起使用的替代方法template
这篇文章主要介绍了vue中v-for和v-if一起使用的替代方法template,使用的版本是vue 2.9.6和element-ui: 2.15.6,通过实例代码给大家讲解的非常详细,需要的朋友可以参考下2022-05-05vue+axios+element ui 实现全局loading加载示例
今天小编就为大家分享一篇vue+axios+element ui 实现全局loading加载示例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧2018-09-09vue3项目如何配置按需自动导入API组件unplugin-auto-import
这篇文章主要介绍了vue3项目如何配置按需自动导入API组件unplugin-auto-import问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教2024-03-03
最新评论