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 vueComponent1
i 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.
źródło
Odpowiedzi:
Z dokumentacji Vue.js.
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();
źródło
movieslist.vue?1be4:38Uncaught TypeError: _resource.Resource is not a constructor
kiedy używam tego ...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ć JavaScriptfetch
API.Z dokumentacji Vue.js na temat tworzenia aplikacji na dużą skalę .
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.
źródło
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(); } ... })
źródło
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:
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.
źródło
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.
źródło
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')
źródło