web-dev-qa-db-fra.com

Vue.js: définir un service

Je considère Vue.js comme une alternative à Angular et je l’aime vraiment jusqu’à présent . Pour en avoir une idée, je suis en train de transformer un projet Angular existant en un projet Vue. Je suis juste au point où je dois communiquer avec mon API REST. 

Dans Angular, je définissais un service pour cela, qui était injecté dans tous les contrôleurs qui en avaient besoin. Vue ne semble pas connaître la construction "service" si je comprends bien. Comment cela peut-il être réalisé dans Vue?

J'ai considéré vue-resource, mais ce n'est que pour les fonctionnalités http, pour autant que je sache. Comme j'utilise jQuery aussi, c'est obsolète.

Exemple:

J'ai vueComponent1 et vueComponent2. Les deux doivent avoir accès à la même ressource REST. Pour gérer cela, je veux un service central, que les deux composants peuvent utiliser pour les demandes adressées à la ressource REST. Angular a le composant 'service', qui fait exactement cela. Vue n'a pas.

54
Herr Derb

De la documentation de Vue.js.

Vue.js n'est pas un framework complet, il se concentre uniquement sur le calque de vue.

En tant que bibliothèque spécialisée dans le MVC, elle ne fournit pas des services tels que des services. 

Utilisez-vous une sorte de chargeur de module tel que Browserify ou Webpack?
Vous pouvez ensuite utiliser le système de modules de ES6 pour créer un service par vous-même.
Tout ce que vous avez à faire est de créer une classe JavaScript simple qui est exportée par ce nouveau module.

Un exemple pourrait ressembler à ceci: 

export default class RestResource {

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

}

Dans vos composants de vue 1 et 2, vous pouvez utiliser ce service en important la classe.

import RestResource from './services/RestResource';

const restResourceService = new RestResource();

restResourceService.sendRequest();
69
Marc

Dans la documentation de Vue.js sur Création d'applications à grande échelle .

La communauté a fourni le plug-in vue-resource , qui permet de travailler facilement avec les API RESTful. Vous pouvez également utiliser n'importe quelle bibliothèque Ajax que vous aimez, par exemple. $ .ajax ou SuperAgent .

Vue ne vous oblige pas à suivre une architecture spécifique, car elle fait uniquement référence à la couche View dans une architecture MVC ou MVVM. Comme @Marc déjà dit dans sa réponse , une bonne pratique consiste à utiliser un chargeur de module tel que Browserify ou Webpack pour pouvoir créer vos "services" dans des fichiers séparés, en les important où vous le souhaitez. Il est très facile de structurer votre application avec un chargeur de module avec vue-cli .

En fait, j'aime beaucoup l'architecture Flux pour les applications basées sur les composants, puis je vous recommande de regarder Vuex , une architecture d'application inspirée de Flux conçue spécifiquement pour la gestion de l'état dans Vue.js applications.

De cette façon, vous pouvez créer des actions qui utilisent vue-resource pour demander votre API, puis vous pouvez envoyer des mutations lorsque les données arrivent, avec tous les composants qui ont besoin de ces données déjà liées à l'état global, réagissant automatiquement. En d'autres termes, vos composants eux-mêmes n'ont pas besoin d'appeler les services, ils réagissent simplement aux changements d'état envoyés par Mutations.

17
Erick Petrucelli

Vous avez de très bonnes réponses à cette question Quel est l'équivalent du service angulaire dans VueJS?

Comme @Otabek Kholikov le dit, vous avez 4 options:

  1. Service sans état: alors vous devriez utiliser mixins
  2. Service Statefull: utilisez Vuex
  3. Exporter le service et importer depuis un code de vue
  4. tout objet global javascript

Dans mes projets je préfère (4). Il me donne le maximum de flexibilité et ne contient que les implémentations dont j'ai besoin (je n'apporte pas par exemple Vuex et ne devrais pas être strict sur ses règles et il n'y a pas de "magie" - tout le code est à moi). Vous avez un exemple de mise en œuvre dans la Question mentionnée ci-dessus.

10
Alexander

Si vous n'utilisez pas de chargeur de module, vous pouvez définir un plugin personnalisé . Quelques exemples de code:

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

Vous pouvez également brancher d’autres bibliothèques, this post montre comment brancher axios.js

4
Michael Tranchida

Vous pouvez exporter l'instance d'une classe pour votre service:

export default new class {
   ...
}

Dans votre composant, ou à tout autre endroit, vous pouvez importer l'instance et vous obtiendrez toujours la même. De cette façon, il se comporte comme un service angulaire injecté, mais sans utiliser this.

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

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

Vous pouvez configurer la ressource vue globalement comme 

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

et maintenant sur chaque appel http, vous pouvez simplement appeler par le nom de ressource -

this.$http.get('');
this.$http.get('users')
0
Sourabh Ranka