非父子组件的通信
Provide/Inject
- Provide/Inject用于非父子组件之间共享数据:
- 比如有一些深度嵌套的组件,子组件想要获取父组件的部分内容;
- 在这种情况下,如果我们仍然将props沿着组件链逐级传递下去,就会非常的麻烦;
- 对于这种情况下,我们可以使用 Provide 和 Inject :
- 无论层级结构有多深,父组件都可以作为其所有子组件的依赖提供者;
- 父组件有一个 provide 选项来提供数据;
- 子组件有一个 inject 选项来开始使用这些数据;
代码结构如下:
在app组件中使用到 provide
选项
在homecontent组件中使用 inject
选项来声明
注入会在组件自身的状态之前被解析,因此你可以在 data()
中访问到注入的属性,如下面的代码所示
//此代码块与上文中的举例无关 export default { inject: ['message'], data() { return { // 基于注入值的初始数据 fullMessage: this.message } } }
如果Provide中提供的一些数据是来自data,那么我们可能会想要通过this来获取:
这个时候会报错:
报错是因为此时的this指向的是script作用域,但在<script></script>
里打印this会发现此时this为undefined,所以此时会报错
如果我们使用provide的函数写法即可解决问题
- 那么,如果我们修改了this.names的内容,那么使用length的子组件会不会是响应式的?
- 我们会发现对应的子组件中是没有反应的:
- 这是因为当我们修改了names之后,之前在provide中引入的 this.names.length 本身并不是响应式的;
- 那么怎么样可以让我们的数据变成响应式的呢?
- 非常的简单,我们可以使用响应式的一些API来完成这些功能,比如说
computed
函数;
- 注意:我们在使用length的时候需要获取其中的value
- 这是因为computed返回的是一个ref对象,需要取出其中的
value
来使用;
Mitt全局事件总线
Vue3从实例中移除了 on、on、on、off 和 $once 方法,所以我们如果希望继续使用全局事件总线,要通过第三方的库
这里我们使用mitt库
- 首先,我们需要先安装这个库:
npm install mitt
- 其次,我们可以封装一个工具eventbus.js:
使用事件总线工具
Mitt的事件取消