Vue.js:定义一个服务

Her*_*erb 69 javascript rest vue.js

我正在考虑将Vue.js作为Angular的替代品,到目前为止我非常喜欢它.为了感受它,我将现有的Angular项目重构为Vue项目.我只是需要与REST API进行通信.

在Angular中,我曾经为此定义了一个服务,它被注入到需要它的每个控制器中.据我所知,Vue似乎并不知道"服务"结构.如何在Vue中实现这一目标?

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

例:

我有vueComponent1vueComponent2.两者都需要访问相同的REST资源.为了解决这个问题,我想要一个中央服务,这两个组件都可以用来处理对REST资源的请求.Angular有"服务​​"组件,正是这样做的.Vue没有.

Mar*_*arc 88

从Vue.js文档.

Vue.js本身并不是一个完整的框架 - 它只关注视图层.

作为一个专注于MV的MV的图书馆,它不提供像服务这样的东西.

您使用的是某种模块加载程序,如Browserify或Webpack吗?
然后,您可以利用ES6的模块系统自行创建服务.
您所要做的就是创建一个由此新模块导出的纯JavaScript类.

示例可能如下所示:

export default class RestResource {

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

}
Run Code Online (Sandbox Code Playgroud)

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

import RestResource from './services/RestResource';

const restResourceService = new RestResource();

restResourceService.sendRequest();
Run Code Online (Sandbox Code Playgroud)

  • 你错过了与Angular背景所期望的一个显着差异.在这种情况下,"服务"被多次实例化,而在共享服务注入中,只传递一个实例 (7认同)
  • 如果您想要“Angular 风格”单例服务,您只需在应用程序中的某个位置创建此类的实例,然后将其导出:“export const RestResourceService = new RestResource();”,然后将其导入到您希望的任何位置。然而,这实际上是为我们自己创建的问题创建一个解决方案 - 为什么不直接使用函数呢?`export function sendRequest() { // Make the request }` 最后,请注意,您甚至不一定需要一个库来发出 http 请求 - 根据您的项目要求,您可以简单地使用 JavaScript `fetch` API。 (7认同)
  • 谢谢你的报价.这意味着在视图和模型下面没有任何结构或任何东西.如果我想要一个服务,我需要建立自己的服务,例如使用纯JS. (2认同)
  • 是的,您可以通过这种方式获得同一服务的多个实例。当它只执行 Ajax 请求时这不是问题(只是效率低下),但是当您将服务用于数据模型时,您需要在声明服务的地方实例化它,并且只导出实例。 (2认同)

Eri*_*lli 19

从关于构建大规模应用程序的Vue.js文档.

社区提供了vue-resource插件,它提供了一种使用RESTful API的简便方法.您也可以使用任何您喜欢的Ajax库,例如$ .ajax或SuperAgent.

Vue不要求您遵循特定的体系结构,因为它仅引用MVC或MVVM体系结构中的View层.正如@Marc他的回答中所说,一个好的做法是使用像Browserify或Webpack这样的模块加载器,这样你就可以在单独的文件中创建"服务",并在需要的地方导入它们.使用vue-cli使用模块加载器构建应用程序非常容易.

事实上,我个人非常喜欢基于组件的应用程序的Flux架构,然后我建议你看看Vuex,这是一个专门用于管理Vue.js应用程序内部状态的Flux灵感应用程序架构.

这样,您可以创建使用vue-resource来请求API的Actions ,然后您可以在数据到达时调度Mutations,所有需要该数据的组件已经绑定到全局State,并自动响应.换句话说,您的组件本身不需要调用服务,它们只是对Mutations调度的状态更改做出反应.

  • 请注意,vue-resource不再是正式推荐的.[源(https://medium.com/the-vue-point/retiring-vue-resource-871a82880af4) (3认同)

Max*_*ola 11

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

export default new class {
   ...
}
Run Code Online (Sandbox Code Playgroud)

在您的组件或任何其他地方,您可以导入实例,并且始终获得相同的实例。这样,它的行为类似于注入的Angular服务,但不使用this

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

Vue.component('my-component', {
  ...
  created: function() {
    myService.oneFunction();
  }
  ...
})
Run Code Online (Sandbox Code Playgroud)


Ale*_*der 10

在这个问题中你有一些非常好的答案在VueJS中相当于Angular Service的是什么?

正如@Otabek Kholikov所说 - 你有4种选择:

  1. 无国籍服务:那你应该使用mixins
  2. Statefull服务:使用Vuex
  3. 从vue代码导出服务和导入
  4. 任何javascript全局对象

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


Mic*_*ida 5

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

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();
        }
    });
Run Code Online (Sandbox Code Playgroud)

您也可以插入其他库,本文介绍如何插入axios.js