Vue.js: Definieren Sie einen Service

84

Ich betrachte Vue.js als Alternative zu Angular und es gefällt mir bisher sehr gut. Um ein Gefühl dafür zu bekommen, überarbeite ich ein vorhandenes Angular-Projekt in ein Vue-Projekt. Ich bin gerade an dem Punkt angelangt, an dem ich mit meiner REST-API kommunizieren muss.

In Angular habe ich dafür einen Service definiert, der in jeden Controller eingefügt wurde, der ihn benötigte. Vue scheint das "Service" -Konstrukt meines Wissens nicht zu kennen. Wie kann dies in Vue erreicht werden?

Ich habe überlegt vue-resource, aber es ist nur für http-Funktionen, soweit ich verstehe. Da ich auch jQuery verwende, ist dies veraltet.

Beispiel:

Ich habe vueComponent1und vueComponent2. Beide benötigen Zugriff auf dieselbe REST-Ressource. Um dies zu handhaben, möchte ich einen zentralen Service, den beide Komponenten für Anforderungen an die REST-Ressource verwenden können. Angular hat die 'Service'-Komponente, die genau das tut. Vue hat nicht.

Herr Derb
quelle
Geben Sie ein konkretes Beispiel dafür, was Sie brauchen. http ist ausreichend, um mit REST
Gurghet
Werfen

Antworten:

96

Aus der Vue.js-Dokumentation.

Vue.js selbst ist kein vollständiges Framework - es konzentriert sich nur auf die Ansichtsebene.

Als Bibliothek, die sich auf das V von MVC konzentriert, bietet sie keine Dienste an.

Verwenden Sie eine Art Modullader wie Browserify oder Webpack?
Dann können Sie das Modulsystem von ES6 nutzen, um selbst einen Service zu erstellen.
Sie müssen lediglich eine einfache JavaScript-Klasse erstellen, die von diesem neuen Modul exportiert wird.

Ein Beispiel könnte so aussehen:

export default class RestResource {

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

}

In Ihren Vue-Komponenten 1 und 2 können Sie diesen Service verwenden, indem Sie die Klasse importieren.

import RestResource from './services/RestResource';

const restResourceService = new RestResource();

restResourceService.sendRequest();
Marc
quelle
2
Danke für das Zitat. Dies bedeutet, dass sich unter Ansicht und Modell keine Struktur oder etwas befindet. Wenn ich einen Service haben möchte, muss ich meinen eigenen erstellen, z. B. mit reinem JS.
Herr Derb
Ich bekomme, movieslist.vue?1be4:38Uncaught TypeError: _resource.Resource is not a constructorwenn ich das benutze ...
George Katsanos
13
Ihnen fehlt ein wesentlicher Unterschied zu dem, was Sie mit einem eckigen Hintergrund erwarten würden. Der "Dienst" wird in diesem Fall mehrmals instanziiert, während bei der gemeinsamen
Dienstinjektion
1
Ja, auf diese Weise erhalten Sie mehrere Instanzen desselben Dienstes. Dies ist kein Problem, wenn nur eine Ajax-Anforderung ausgeführt wird (lediglich ineffizient). Wenn Sie den Dienst jedoch für Ihr Datenmodell verwenden, müssen Sie ihn dort instanziieren, wo Sie den Dienst deklarieren, und nur die Instanz exportieren.
mcv
2
Wenn Sie einen Singleton-Dienst im 'Angular-Stil' möchten, können Sie einfach irgendwo in Ihrer App eine Instanz dieser Klasse erstellen und exportieren: export const restResourceService = new RestResource();und dann importieren, wo immer Sie möchten. Dies schafft jedoch wirklich eine Lösung für ein Problem, das wir für uns selbst erstellt haben - warum nicht einfach eine Funktion verwenden? export function sendRequest() { // Make the request } Beachten Sie schließlich, dass Sie nicht unbedingt eine Bibliothek benötigen, um eine http-Anfrage zu stellen. Abhängig von Ihren Projektanforderungen können Sie einfach die JavaScript- fetchAPI verwenden.
Will Taylor
21

Aus der Vue.js-Dokumentation zum Erstellen umfangreicher Apps .

Die Community hat das Vue-Resource- Plugin beigesteuert , das eine einfache Möglichkeit bietet, mit RESTful-APIs zu arbeiten. Sie können auch eine beliebige Ajax-Bibliothek verwenden, z. B. $ .ajax oder SuperAgent .

Für Vue müssen Sie keiner bestimmten Architektur folgen, da es sich nur auf die Ansichtsebene in einer MVC- oder MVVM-Architektur bezieht. Wie @Marc bereits in seiner Antwort sagte, empfiehlt es sich , einen Modullader wie Browserify oder Webpack zu verwenden, damit Sie Ihre "Dienste" in separaten Dateien erstellen und dort importieren können, wo Sie sie benötigen. Es ist sehr einfach, Ihre App mit einem Modullader mit vue-cli zu strukturieren .

Tatsächlich mag ich die Flux- Architektur für komponentenbasierte Apps persönlich sehr. Dann empfehle ich Ihnen, sich Vuex anzusehen , eine von Flux inspirierte Anwendungsarchitektur, die speziell für die Verwaltung des Status in Vue.js Apps entwickelt wurde.

Auf diese Weise können Sie Aktionen erstellen, die vue-resource verwenden , um Ihre API anzufordern. Anschließend können Sie Mutationen auslösen, wenn die Daten eintreffen. Alle Komponenten, für die diese Daten bereits an den globalen Status gebunden sind, reagieren automatisch. Mit anderen Worten, Ihre Komponenten selbst müssen die Dienste nicht aufrufen, sondern reagieren nur auf Statusänderungen, die durch Mutationen ausgelöst werden.

Erick Petrucelli
quelle
4
Nur ein Hinweis, dass vue-resource nicht mehr offiziell empfohlen wird. Quelle
Lichtschalter05
1
Überprüfen Sie die Details: Ruhestand Vue-Ressource geschrieben von Evan You
JeffMinsungKim
17

Sie können die Instanz einer Klasse für Ihren Dienst exportieren:

export default new class {
   ...
}

In Ihrer Komponente oder an einem anderen Ort können Sie die Instanz importieren und Sie erhalten immer dieselbe. Auf diese Weise verhält es sich ähnlich wie ein injizierter Angular-Dienst, jedoch ohne Verwendung this.

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

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

Sie haben in dieser Frage einige sehr gute Antworten darauf. Was entspricht Angular Service in VueJS?

Wie @Otabek Kholikov dort sagt - Sie haben 4 Möglichkeiten:

  1. Staatenloser Service: Dann sollten Sie Mixins verwenden
  2. Statefull Service: Verwenden Sie Vuex
  3. Service exportieren und aus einem Vue-Code importieren
  4. ein beliebiges globales Javascript-Objekt

In meinen Projekten bevorzuge ich (4). Es gibt mir die maximale Flexibilität und hat nur die Implementierungen, die ich brauche (ich bringe zum Beispiel kein Vuex mit und sollte nicht streng nach seinen Regeln sein und es gibt keine "Magie" - der gesamte Code gehört mir). Sie haben ein Beispiel für die Implementierung in der oben erwähnten Frage .

Alexander
quelle
6

Wenn Sie keinen Modullader verwenden, können Sie ein benutzerdefiniertes Plugin definieren . Ein Beispielcode:

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

Sie können auch andere Bibliotheken anschließen. In diesem Beitrag wird gezeigt, wie Sie axios.js einbinden

Michael Tranchida
quelle
1

Sie können die Vue-Ressource global als konfigurieren

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

und jetzt können Sie bei jedem http-Aufruf einfach unter dem Namen der Ressource aufrufen -

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