Vue.js: define a service

我在考虑 Vue.js 作为 Angular 的替代品,到目前为止我真的很喜欢它。 为了获得一种感觉,我正在将一个现有的 Angular 项目重构为一个 Vue 项目。我只是需要与我的 REST API 进行通信。

在 Angular 中,我曾经为此定义了一个服务,它被注入到每个需要它的控制器中。Vue 似乎并不像我理解的那样了解“服务”结构。如何在 Vue 中实现这一点?

我考虑过 vue-resource,但据我所知,它只适用于 http 功能。因为我也使用 jQuery,所以这已经过时了。

例如:

I have vueComponent1 and vueComponent2. Both need access to the same REST resource. To handle this I want a central service, which both of the components can use for requests to the REST resource. Angular has the 'service' component, which exactly does that. Vue hasn't.

96244 次浏览

来自 Vue.js 文档。

Js 本身并不是一个成熟的框架——它只关注于视图层。

作为一个专注于 MVC 之外的 V 的库,它不提供服务之类的东西。

您是否使用某种类型的模块加载程序,如 Browserify 或 Webpack?
然后您可以利用 ES6的模块系统自己创建一个服务。
All you have to do is to create a plain JavaScript class which is being exported by this new module.

An example could look like this:

export default class RestResource {


sendRequest() {
// Use vue-resource or any other http library to send your request
}


}

在 vue 组件1和2中,可以通过导入类来使用此服务。

import RestResource from './services/RestResource';


const restResourceService = new RestResource();


restResourceService.sendRequest();

来自 构建大型应用程序上的 Vue.js 文档。

社区贡献了 vue-resource插件,它提供了一种使用 RESTful API 的简单方法。您还可以使用任何您喜欢的 Ajax 库,例如 $。Ajax 或 超级特工

Vue 不要求您遵循特定的体系结构,因为它只引用 MVC 或 MVVM 体系结构中的 View 层。正如 @ Marchis answer中已经说过的,一个好的实践是使用像 Browserify 或 Webpack 这样的模块加载器,这样您就可以在单独的文件中创建“服务”,并在需要的地方导入它们。通过使用 vue-cli的模块加载器来构建应用程序是非常容易的。

事实上,我个人非常喜欢基于组件的应用程序的 变化架构,那么我建议你看看 烦人,一个受 Flux 启发的应用程序架构,它是专门为 Vue.js 应用程序内部的状态管理而设计的。

通过这种方式,您可以创建使用 价值资源请求 API 的 Actions,然后您可以在数据到达时分派 Mutations,所有需要该数据的组件都已经绑定到全局状态,并自动进行响应。换句话说,您的组件本身不需要调用服务,它们只是对 Mutations 发出的状态更改作出响应。

如果你不使用模块加载器,你可以定义一个定制的 插件。一些示例代码:

var myPlugin = {
install: function (Vue, options) {
//private
var myPrivateProperty = 'Private property';


//instance properties and methods
Vue.prototype.$myPublicProperty = 'Public Property';


Vue.prototype.$myAddedMethod = function () {
return myPrivateProperty;
};
Vue.prototype._getData = function (url) {
return url;
};


//static properties and methods
Vue.myStaticProperty = 'My static prop';
Vue.myStaticMethod = function () {
console.log('in');
}
}
};


Vue.use(myPlugin);


new Vue({
el: '#app',
created: function () {
//using instance
console.log(this.$myAddedMethod());
console.log('my get data: ' + this._getData('some url'));
console.log(this.$myPublicProperty);


//using static
console.log(Vue.myStaticProperty);
Vue.myStaticMethod();
}
});

You can also plug in other libraries, 这篇文章 shows how to plug in axios.js

在这个问题 在 VueJS 中 Angular Service 的等价物是什么?中你有一些非常好的答案

正如@Otabek Kholikov 所说,你有4个选择:

  1. 无状态服务: 然后您应该使用 Mixin
  2. 全状态服务: 使用 Vuex
  3. 从 vue 代码导出服务和导入
  4. 任何 javascript 全局对象

在我的项目中,我更喜欢(4)。它给了我最大的灵活性,并且只有我需要的实现(例如,我没有带来 Vuex,不应该严格遵守它的规则,也没有“魔法”——所有代码都是我的)。在上面提到的 提问中有一个实现的例子。

You can configure vue resource globally as

Vue.http.options.root = "your base url"

现在,在每个 http 调用中,您都可以通过 resource-的名称进行调用

this.$http.get('');
this.$http.get('users')

您可以为您的服务导出类的实例:

export default new class {
...
}

在您的组件或任何其他位置,您可以导入实例,并且总是得到相同的实例。这样,它的行为类似于一个注入的 Angular 服务,但不使用 this

import myService from '../services/myservice';


Vue.component('my-component', {
...
created: function() {
myService.oneFunction();
}
...
})

可以在创建 Vue 实例时指定 Vue-Instance 特定的服务

new Vue({
el: '#app-container',
myService: new MyService()
})

并从您的组件中访问它们,作为

this.$root.$options.myService.doStuff()

Answer for 2022

对于有状态服务,使用内置的 Vue 状态管理: https://vuejs.org/guide/scaling-up/state-management.html

或者用于高级用例的 Pinia (以前是 Vuex) : https://pinia.vuejs.org/