Vue 3 是否支持 Angular-Services 之类的东西?

分享于2022年07月17日 angularjs porting vue.js 问答
【问题标题】:Vue 3 是否支持 Angular-Services 之类的东西?(Does Vue 3 support something like Angular-Services?)
【发布时间】:2022-06-10 19:54:06
【问题描述】:

我正在将一个项目从 AngularJs 移植到 Vue3。在 Angular 中,我们有一个服务组件,它为组件创建和提供对象。如果在组件的绑定中使用这些对象,它们会自动响应。如果组件 A 改变了一个对象,组件 B 的 View 会立即显示状态的变化。

Does Vue 3 support something like Angular-Services?

有没有办法在 Vue3 中完成这样的服务?目标是,维护一个对象数组,数组的每一次变化都会反映在不同组件的Views中。

  • 您是否正在寻找“商店”?像vue pinia。 Pinia 是一种比 vuex 更灵活的方式。它使数据保持集中,无论它从什么组件发生变异和获取。 (如果写得正确)
  • Vue 没有专门的实体。这是可组合函数通常扮演的角色。由于组合 API,它们是反应性的。对于全局服务(单例)组合 api 只是直接在模块中使用,因此它被评估一次并在组合之间共享。正如刚才所说,松果店也可以扮演这个角色。可以有多个商店,它们可以按组合实例化并反映本地状态

【解决方案1】:

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 组合。