理解 Angular/Vue 依赖注入

最近面试问到了 Vue 组件间传值的问题,关于这个问题基本的那些 api 就不用多说了,但是夜深人静时突然思考什么时候需要组件间传值?解决了什么问题?有什么复杂的业务场景?

不由得又想到了 Angular 的依赖注入,感觉如果我自己是面试官一定会问一下 Angular 和 Vue 有什么区别,如果回答一个重一个轻就属实有点过于拉垮了。

总的来说,这些问题的本质在于对于目前模块化的前端开发来说,数据交互方面的最佳实践是什么,基于这个前提再去理解依赖注入就好很多了。

一、依赖注入的目的

解耦!不使用依赖注入时,我们想要使用另一个模块往往都是通过 new 一个新的实例的方式来实现。这样会带来两个问题:

  • 耦合度高
  • 每一个 new 都是新的,数据无法共享

而使用依赖注入的方式,则是将一个已经存在的实例或是服务注入进来,业务上能够解耦,并且只有一个,有点类似于单例模式 + 观察者模式。

参考文章:详解 Angular 依赖注入

二、依赖注入适合做什么

2.1、业务组件

什么是组件?就是可复用且易于维护的最小单元,而在实际的开发中其实真正符合这样的组件并不多,大部分是按钮、输入框一类的基础组件,而这类基础组件也已经被 Element、AntDesign 这类 UI 框架所实现,需要我们重复造轮子的情况不多。

那么问题来了,真正在项目开发中开发的组件,往往是只在一处使用的业务单元,这类业务单元组件很多时候又面临着多级嵌套和兄弟级的情况,这样情况下的组件通信一般来说有两种方案:

  • Event Bus
  • props 逐级传递
  • 依赖注入

来看这三种方案,Event Bus 面临的问题是需要组件们都要对这些事件进行相应的订阅、发送、取消,当组件多的时候会逐渐变得不利于维护,而通过 props 逐级传递则对于不需要该数据的中间组件来说又显得多余。

通常,当我们需要从父组件向子组件传递数据时,我们使用 props。想象一下这样的结构:有一些深度嵌套的组件,而深层的子组件只需要父组件的部分内容。在这种情况下,如果仍然将 prop 沿着组件链逐级传递下去,可能会很麻烦。

而这时候就可以使用依赖注入了,为什么要特别强调是业务组件呢?因为如果要使用 Provide/Inject 依赖注入的方式那就必须要保证 Provide 是在祖先组件链上的,因此破坏了组件的可复用性,而业务组件更多的可能只是为了易于维护而存在的,可以牺牲掉可复用性。

理解 Angular/Vue 依赖注入_第1张图片

参考文章:小编不才,愿与你聊聊 vue 中的依赖注入

2.2 全局组件和服务

另一种场景,则是整个系统都需要的组件或者服务,这样的话你的整个系统是 Provide,就不存在上文说的可复用性问题了。

经典的比如说消息订阅服务,不管我在哪个页面在干什么,只要系统接受到了消息,我就要在所有需要显示新消息角标的地方来动态的更新,这种情况在 Vue/React 中可以使用 Vuex/Redux 这类状态管理工具来实现。而 Angular 安装这类状态管理工具又略显冗余,就可以自己实现一个单例服务,然后将该服务注入到需要使用的地方即可。

或者不满足于前文提到的 UI 框架提供的公用组件,想自己重新造一个轮子,也可以使用依赖注入进行实现,之前做的项目中由于组件库提供的 loading 样式组件无法满足需求,因此项目重新封装了一个 LoaderService 来提供给全局使用,多个地方同时请求接口等待回调时就会触发 loading 样式,而重复触发、倒计时消失等功能就都是在这个 LoaderService 中统一管理的,类似的还有 http 请求拦截器也是通过依赖注入的方式完成的:

// HTTP_INTERCEPTORS:Angular 自己的 http 处理方法
// ApiInterceptor:自己封装的 http 处理方法
{ provide: HTTP_INTERCEPTORS, useClass: ApiInterceptor }

你可能感兴趣的:(项目积累,前端)