Vue 是 UI 框架,没有专门的实体,如服务,由开发人员来实现它们。与 Angular 不同,Vue 不提供 DI 功能。
在 Vue 中,可重用的组件代码应该由可组合函数提供,它们的反应性是通过组合 API 实现的:
// Usage: useLocalService()
const useLocalService = () => {
const someState = reactive({});
const someAction = () => /* change state */;
return { someState, someAction }
};
对于 Angular 中固有的全局单例服务,服务状态在一个模块中定义并评估一次,因此它在整个应用程序中共享:
// Usage: import * as globalService from '...';
export const someGlobalState = reactive({});
export const someGlobalAction = () => /* change state */;
将其包装在可组合函数中以保持一致性是否有益取决于具体情况:
// Usage: useGlobalService()
const someGlobalState = reactive({});
const someGlobalAction = () => /* change state */;
const useGlobalService = () => {
return { someGlobalState, someGlobalAction }
};
在 Angular 2 或更高版本中,DI 容器允许为每个组件层次结构提供服务实例。在 Vue 中,这是通过
provide
/
inject
完成的:
// Usage in a parent: setupRootOrNestedService()
const setupRootOrNestedService = () => {
const someRootOrNestedState = reactive({});
const someRootOrNestedAction = () => /* change state */;
provide('rootOrNestedService', { someRootOrNestedState, someRootOrNestedState });
};
// Usage in a child: useRootOrNestedService()
const useRootOrNestedService = () => {
return inject('rootOrNestedService');
};
这允许在任何级别通过令牌识别服务,并从使用 DI 模式中受益。
Pinia 提供受 Flux 模式影响的轻量级状态管理,该模式依赖于组合 API 并允许多个存储。结果与上面类似,加上 Vue devtools 的支持和正确的 TypeScript 输入:
// Usage as local service: useLocalOrGlobalService()
// Usage as global service: export default useLocalOrGlobalService()
const useLocalOrGlobalService = () => {
return defineStore('localOrGlobalService' + random(), {
state: () => ({}),
actions: {
someAction() { /* change state */ }
}
})
};
Pinia 不限制 store 实例化和提供给组件的方式,因此可以在必要时与
provide
/
inject
组合。