前言
从做前端开始我就一直在使用vue,但随着业务的不断发展,我开始力不从心维护逐渐庞大的代码,即使上ts,人为规范代码。我觉得可能是技能不够多,接触面不够宽逛导致的,所以我便逐渐开始使用学习react,ng。 后来随着我不断的使用ng,发现ng的依赖注入模式非常工程,代码维护起来非常清晰。但是ng非常重,公司的业务都是vue,我不可能切换到ng 再后来伴随着vue3的升级,ts支持也逐渐完善,我就想在vue3上实现一个简单的模仿ng的依赖注入库
Vdi
这是我一个在业务上试验了很久,基于redi增强vue依赖注入开发的库,从最开始就考虑到了同事不可能完全就接受vue所有api都基于依赖注入,所以渐进只用两个hook api也能完整体验redi的依赖注入,这样侵入性小,学习成本也小。
不过如果希望整个项目都基于依赖注入模式,vdi也提供了vueModule模式,vdi在此之上把vue-router
,Directive
等api都封装成了依赖注入模式。
文档
快速启动模板
小例子
前面废话了这么多,来让我们看看vue基于vdi的依赖注入都能干点什么,不喜欢看文章也可以看看快速启动模板我把大部分api都用了一下
简单的状态管理
首先我们创建一个服务,用ref创建响应式数据
// count.service.tsimport { ref } from 'vue'export class CountService { count = ref<number>(0) inc() { this.count.value++ }}
然后在希望使用这个数据的组件或者顶层注入这个服务
<script setup lang="ts">import { onProvider, useDependency } from 'vdi'import { CountService } from './count.service'//在当前组件注入依赖onProvider([[CountService]])//获取提供的依赖,self为true时候获取的是当前组件的依赖const countService = useDependency(CountService, { self: true })</script><template> {{ countService.count }} <button @click="countService.inc">修改</button></template>
之后在此组件树结构之下的组件便能获取到,此组件的服务状态
<!--Child.vue --><script setup lang="ts">import { onProvider, useDependency } from 'vdi'import { CountService } from './count.service'const countService = useDependency(CountService)</script><template> <div class="child"> 子组件: {{ countService.count }} <button @click="countService.inc">count+</button> </div></template>
如果只是希望获取到服务当做hook用,而不触发修改父组件的状态,只需要onProvider在组件中重新注入服务就能得到一个最初状态的服务。
vdi基于依赖注入实现还有其他功能,比如:
APP_INITIALIZER - 可以在vue实例挂载之前发送请求,等待请求结束再挂载vue实例,并且可以把请求数据注入vue实例中
useOverlay - 一个简单帮助你把组件库如element-plus
,antd-vue
弹出层组件变成promise形式,在弹出层子组件触发close再执行then,不用在template中写弹出层标签的hook
当然你也可以自己基于vdi实现很多功能,比如全局注入一个请求服务的标识,组件库也都调这个请求服务的标识发送请求,这样不管请求库是axios
,fetch
只要跟定义的一样就能轻松替换。
最后
这是我的第一个库,有很多稚嫩的地方,文档写的很烂,发布和github commit也是一团糟,希望大家体谅,给我一些意见
原文:https://juejin.cn/post/7099828064485376030