Vue.js:定义服务


84

我正在寻找Vue.js作为Angular的替代产品,到目前为止我真的很喜欢。为了感受一下,我将现有的Angular项目重构为Vue项目。我正好需要与REST API通信。

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

我考虑过了vue-resource,但据我了解,它仅用于http功能。当我也使用jQuery时,这已经过时了。

例:

我有vueComponent1vueComponent2。两者都需要访问相同的REST资源。为了解决这个问题,我需要一个中央服务,这两个组件都可以用于对REST资源的请求。Angular具有“服务”组件,正是这一点。Vue还没有。


提供您需要的具体示例。http足以与REST通信
gurghet '16

Answers:


96

来自Vue.js文档。

Vue.js本身不是一个完善的框架-它仅关注视图层。

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

您是否正在使用某种模块加载器,例如Br​​owserify或Webpack?
然后,您可以利用ES6的模块系统自行创建服务。
您要做的就是创建一个普通的JavaScript类,此新模块将导出该类。

一个示例可能如下所示:

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();

2
感谢您的报价。这意味着视图和模型下面没有结构或任何东西。如果我想拥有一项服务,则需要构建自己的服务,例如使用纯JS。
Derb先生

movieslist.vue?1be4:38Uncaught TypeError: _resource.Resource is not a constructor使用它时会得到...
乔治·卡萨诺斯

13
您缺少与Angular背景所期望的明显区别。在这种情况下,“服务”被实例化了多次,而在共享服务注入中,仅传递了一个实例
phil294

1
是的,您可以通过这种方式获得同一服务的多个实例。当它仅执行Ajax请求(效率很低)时,这不是问题,但是当您将服务用于数据模型时,您需要在声明服务的地方实例化它,并仅导出实例。
mcv

2
如果您想要“角度样式”单例服务,则可以在应用程序中的某个位置简单地创建此类的实例,export const restResourceService = new RestResource();然后将其导出:然后将其导入到任何需要的位置。但是,这确实为我们为自己创建的问题创建了解决方案-为什么不仅仅使用函数? export function sendRequest() { // Make the request } 最后,请注意,您甚至不需要库就可以发出http请求-根据您的项目要求,您可以简单地使用JavaScript fetchAPI。
威尔·泰勒

21

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

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

Vue不需要您遵循特定的架构,因为它仅指MVC或MVVM架构中的View层。正如@Marc回答中所说的那样,一个好的做法是使用诸如Browserify或Webpack之类的模块加载器,以便您可以在单独的文件中创建“服务”,然后将它们导入所需的位置。使用vue-cli使用模块加载器来构建您的应用非常容易。

确实,我个人非常喜欢基于组件的应用程序的Flux体系结构,然后建议您看一下Vuex,这是一种受Flux启发的应用程序体系结构,专门用于管理Vue.js应用程序中的状态。

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


4
请注意,不再正式建议使用vue-resource。来源
lightswitch05 '18

1
查看详细信息:由Evan You
JeffMinsungKim

17

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

export default new class {
   ...
}

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

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

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

11

在这个问题中,您对此有一些很好的答案。VueJS中的Angular Service相当于什么?

正如@Otabek Kholikov所说的那样-您有4种选择:

  1. 无状态服务:那么您应该使用mixins
  2. 全状态服务:使用Vuex
  3. 导出服务并从vue代码导入
  4. 任何JavaScript全局对象

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


6

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

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();
        }
    });

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


1

您可以将vue资源全局配置为

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

现在,在每个http调用上,您只需按资源名称进行调用-

this.$http.get('');
this.$http.get('users')
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.