背景
在开发中,我们构建了组件树之后,除了父子组件之间的通信之外,还会有非父子组件之间的通信,比如兄弟组件、不同页面的几个组件之间。
目前主流的有3种方式:
1、Provide/Inject 依赖/注入 (官方,适合少量数据,用得少,兄弟间不能用)
2、Mitt全局事件总线(第三方,通过监听事件传递数据)
3、Vuex(官方,适合大量数据共享,用得多)
也可以用其他的,如利用浏览器储存 https://www.yuque.com/yejielin/mypn47/hmyecw
=====================
Provide/Inject 依赖/注入
基本介绍
优点
缺点
1、兄弟之间不能用,只适用于父传个某个后代组件(子、孙子、曾孙子…..),父组件的兄弟及其下的组件也没办法获取到。
2、命名问题,同名的变量会覆盖。
用法
vue 2.x
父组件
对象形式,会有this指向问题(指向的是script这个模块,是undefined),建议用函数形式
或者
函数形式,this指向data。
另外Provide 不是响应式的,如果上图的name是个数组,数组长度变化了,provide引用数组.length是不会变的。
要怎么才能有?用计算属性包裹
孙子组件
Vue 3
父组件
上图的length通过计算属性变成响应式的,相当于是一个Ref对象,子组件需要通过length.value获取值3
(length)
子组件
Vue 3.x 组合API
父组件
(非响应式)
或者
(用 ref 或 reactive 包裹就是响应式)
(响应式,父组件内发生改变,孙子组件接收最新的;然后把这个父组件的方法,提供给孙子组件,通过孙子调用来修改)
孙子组件
(vue 2.x,可以和vue 3.x的混合用,但这样非响应式)
或者
(非响应式)
或者
(响应式,孙子组件接收父组件提供的方法,使用方法来通过父组件改变)
孙子自己弄一个方法去改变父组件的值,也是可以的,但是不建议这样弄,这样会比较乱。提供方的东西最好让提供方自己改,否则多个子组件同时改会有问题。
因此可以改为readonly,这样还是响应式,而且子组件无法直接改。
=====================
全局事件总线mitt库
介绍
某个组件发出一个事件A,其他单个或多个组件可以监听这个事件A,如果事件A执行了,其他组件执行自己的事件BCDE….
原理
安装
npm install mitt -S
封装
utils是工具的意思,一般存放一些通用的函数,给项目所有的组件使用
使用
Vue 3.x
about组件:
btnClick事件执行时,会发出一个事件,事件类型是”why”,参数是后面的那个对象
(可以同时发出多个事件)
homeContent组件:
通过on监听类型为”why”的事件,然后执行一个函数。
也就是只要按钮点击,就会发出一个why事件,只要监听这个事件的组件,都会执行他们对应的代码。
很像聊天室,有个人发送了信息,其他人监听聊天窗口,因此都能收到信息并在自己界面上显示
(可以同时监听多个事件,*表示所有类型的事件)
取消监听
=====================
VueX
用的多,是Vue 官方的模块,需要独立安装,适合大量数据共享,不管什么组件都可以拿数据。
查看 https://www.yuque.com/yejielin/mypn47/gqfk8w