Vue.js: zdefiniuj usługę

90

Patrzę na Vue.js jako alternatywę dla Angular i jak dotąd bardzo mi się podoba. Aby to poczuć, refaktoryzuję istniejący projekt Angular na projekt Vue. Jestem w momencie, w którym muszę się komunikować z moim interfejsem API REST.

W Angular definiowałem usługę do tego, która była wstrzykiwana do każdego kontrolera, który tego potrzebował. Wydaje się, że Vue nie zna konstrukcji „usługi”, jak rozumiem. Jak można to osiągnąć w Vue?

Rozważałem vue-resource, ale to tylko dla funkcjonalności http, o ile rozumiem. Ponieważ ja również używam jQuery, jest to przestarzałe.

Przykład:

Mam vueComponent1i vueComponent2. Obie potrzebują dostępu do tego samego zasobu REST. Aby sobie z tym poradzić, potrzebuję usługi centralnej, której oba komponenty mogą używać do wysyłania żądań do zasobu REST. Angular ma komponent „service”, który dokładnie to robi. Vue nie.

Herr Derb
źródło
Podaj konkretny przykład tego, czego potrzebujesz. http wystarczy do komunikacji z REST
gurghet
Zajrzyj na vue-resource: github.com/vuejs/vue-resource
nils.

Odpowiedzi:

99

Z dokumentacji Vue.js.

Sam Vue.js nie jest pełnoprawnym frameworkiem - skupia się tylko na warstwie widoku.

Jako biblioteka skupiająca się na V z MVC, nie zapewnia takich usług.

Czy używasz jakiegoś modułu ładującego, takiego jak Browserify lub Webpack?
Następnie możesz wykorzystać system modułowy ES6 do samodzielnego stworzenia usługi.
Wszystko, co musisz zrobić, to utworzyć zwykłą klasę JavaScript, która będzie eksportowana przez ten nowy moduł.

Przykład mógłby wyglądać tak:

export default class RestResource {

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

}

Wewnątrz komponentu 1 i 2 vue możesz korzystać z tej usługi, importując klasę.

import RestResource from './services/RestResource';

const restResourceService = new RestResource();

restResourceService.sendRequest();
Marc
źródło
2
Dzięki za wycenę. Oznacza to, że pod widokiem i modelem nie ma żadnej struktury ani niczego. Jeśli chcę mieć usługę, muszę zbudować własną, np. Używając czystego JS.
Herr Derb
Dostaję, movieslist.vue?1be4:38Uncaught TypeError: _resource.Resource is not a constructorkiedy używam tego ...
George Katsanos,
14
Brakuje Ci jednej znaczącej różnicy w stosunku do tego, czego można by oczekiwać na tle Angular. W tym przypadku instancja „usługi” jest tworzona wiele razy, podczas gdy w przypadku wstrzykiwania usługi współużytkowanej przekazywana jest tylko jedna instancja
phil294
2
Tak, w ten sposób otrzymujesz wiele wystąpień tej samej usługi. Nie stanowi to problemu, gdy po prostu wykonuje żądanie Ajax (po prostu nieefektywne), ale kiedy używasz usługi dla swojego modelu danych, musisz utworzyć jej wystąpienie w miejscu, w którym deklarujesz usługę i wyeksportować tylko instancję.
mcv
5
Jeśli potrzebujesz usługi singletonowej w stylu Angular, możesz po prostu utworzyć instancję tej klasy gdzieś w swojej aplikacji i wyeksportować ją, export const restResourceService = new RestResource();a następnie zaimportować w dowolnym miejscu. Jednak tak naprawdę jest to rozwiązanie problemu, który stworzyliśmy dla siebie - dlaczego po prostu nie użyć funkcji? export function sendRequest() { // Make the request } Na koniec pamiętaj, że niekoniecznie potrzebujesz biblioteki do wysyłania żądania http - w zależności od wymagań projektu możesz po prostu użyć JavaScript fetchAPI.
Will Taylor
22

Z dokumentacji Vue.js na temat tworzenia aplikacji na dużą skalę .

Społeczność udostępniła wtyczkę vue-resource , która zapewnia łatwy sposób pracy z interfejsami API RESTful. Możesz także użyć dowolnej biblioteki Ajax, np. $ .Ajax lub SuperAgent .

Vue nie wymaga od ciebie przestrzegania określonej architektury, ponieważ odnosi się tylko do warstwy widoku w architekturze MVC lub MVVM. Jak już @Marc powiedział w swojej odpowiedzi , dobrą praktyką jest użycie modułu ładującego moduły, takiego jak Browserify lub Webpack, aby móc tworzyć swoje „usługi” w oddzielnych plikach, importując je tam, gdzie są potrzebne. Tworzenie struktury aplikacji za pomocą modułu ładującego moduł przy użyciu vue-cli jest bardzo łatwe .

Rzeczywiście, osobiście bardzo lubię architekturę Flux dla aplikacji opartych na komponentach, więc polecam przyjrzeć się Vuex , architekturze aplikacji inspirowanej Flux, która została zaprojektowana specjalnie do zarządzania stanem w aplikacjach Vue.js.

W ten sposób możesz tworzyć akcje, które używają zasobu vue do żądania interfejsu API, a następnie możesz wysyłać mutacje, gdy nadejdą dane, ze wszystkimi komponentami, które potrzebują tych danych, już powiązanymi ze stanem globalnym, reagując automatycznie. Innymi słowy, komponenty same nie muszą wywoływać usług, po prostu reagują na zmiany stanu wysyłane przez mutacje.

Erick Petrucelli
źródło
4
Tylko uwaga, że ​​zasoby vue nie są już oficjalnie zalecane. źródło
włącznik świateł05
1
Sprawdź szczegóły:
Wycofanie
1
Axios jest obecnie zalecaną wtyczką zamiast vue-resource.
Luis Martin
19

Możesz wyeksportować wystąpienie klasy dla swojej usługi:

export default new class {
   ...
}

W swoim komponencie lub w dowolnym innym miejscu możesz zaimportować instancję i zawsze otrzymasz tę samą. W ten sposób zachowuje się podobnie do wstrzykniętej usługi Angular, ale bez użycia this.

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

Vue.component('my-component', {
  ...
  created: function() {
    myService.oneFunction();
  }
  ...
})
Max Oriola
źródło
12

Masz na to bardzo dobre odpowiedzi w tym pytaniu. Jaki jest odpowiednik usługi Angular w VueJS?

Jak mówi @Otabek Kholikov - masz 4 opcje:

  1. Usługa bezstanowa: wtedy powinieneś używać mixinów
  2. Pełna obsługa: korzystaj z Vuex
  3. Eksportuj usługę i importuj z kodu vue
  4. dowolny obiekt globalny javascript

W moich projektach preferuję (4). Daje mi maksymalną elastyczność i ma tylko te implementacje, których potrzebuję (nie przynoszę np. Vuex i nie powinienem być rygorystyczny i nie ma tu „magii” - cały kod jest mój). Masz przykład realizacji w pytaniu , o którym wspomniałem powyżej.

Aleksandra
źródło
6

Jeśli nie używasz modułu ładującego, możesz zdefiniować niestandardową wtyczkę . Przykładowy kod:

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

Możesz także podłączyć inne biblioteki, ten post pokazuje, jak podłączyć axios.js.

Michael Tranchida
źródło
1

Możesz skonfigurować zasób vue globalnie jako

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

a teraz przy każdym wywołaniu http możesz po prostu wywołać nazwę zasobu -

this.$http.get('');
this.$http.get('users')
Sourabh Ranka
źródło