Was entspricht Angular Service in VueJS?


94

Ich möchte alle meine Funktionen, die mit dem Server kommunizieren und Daten abrufen, in einer einzigen wiederverwendbaren Datei in VueJS zusammenfassen.

Plugins scheinen nicht die beste Alternative zu sein. Vorlage weniger Komponenten ..?

Antworten:


57

Insgesamt gibt es 4 Möglichkeiten:

  • Staatenloser Service: Dann sollten Sie Mixins verwenden
  • Stateful Service: Verwenden Sie Vuex
  • Service exportieren und aus einem Vue-Code importieren
  • ein beliebiges globales Javascript-Objekt

4
Es scheint sehr umständlich zu sein, die Vuex-Kuriositäten beim Aufrufen von Methoden mit Zeichenfolgenliteralen für Dienste einzuhalten, wenn Sie eine TypeScript / JS-Klasse erstellen könnten, die den Status und die Logik dafür enthält. Wie können Sie eine Stateful-Klasse als Service in Vue verwenden?
Douglas Gaskell

37

Ich verwende Axios als HTTP-Client für API-Aufrufe. Ich habe einen gatewaysOrdner in meinem srcOrdner erstellt und Dateien für jedes Backend abgelegt , um Axios-Instanzen wie folgt zu erstellen

myApi.js

import axios from 'axios'
export default axios.create({
  baseURL: 'http://localhost:3000/api/v1',
  timeout: 5000,
  headers: {
    'X-Auth-Token': 'f2b6637ddf355a476918940289c0be016a4fe99e3b69c83d',
    'Content-Type': 'application/json'
  }
})

Jetzt in Ihrer Komponente können Sie eine Funktion haben, die Daten wie folgt von der API abruft:

methods: {
 getProducts () {
     myApi.get('products?id=' + prodId).then(response =>  this.product = response.data)
  }
}

Da ich davon ausgehe , dass Sie diese Methode in mehreren Komponenten wiederverwenden möchten, können Sie Mixins von vue.js verwenden:

Mixins sind eine flexible Möglichkeit, wiederverwendbare Funktionen für Vue-Komponenten zu verteilen. Ein Mixin-Objekt kann beliebige Komponentenoptionen enthalten. Wenn eine Komponente ein Mixin verwendet, werden alle Optionen im Mixin in die eigenen Optionen der Komponente „gemischt“.

Sie können also eine Methode in mixin hinzufügen, die in allen Komponenten verfügbar ist, in denen mixin gemischt wird. Siehe folgendes Beispiel:

// define a mixin object
var myMixin = {
  methods: {
     getProducts () {
         myApi.get('products?id=' + prodId).then(response =>  this.product = response.data)
      }
  }
}

// define a component that uses this mixin
var Component = Vue.extend({
  mixins: [myMixin]
})

// alternate way to have a mixin while initialising
new Vue({
  mixins: [myMixin],
  created: function () {
    console.log('other code')
  }
})

3
Wie werden Sie X-Auth-Token von myApi.js aktualisieren, wenn sich der Benutzer
anmeldet

3
Normalerweise ist dies kein statischer Wert
Amarjit Singh

30

Ich benutze hauptsächlich Vue Resource.

1.Ich erstelle eine neue Datei, in der ich mit Vue.http.xxx.O eine Verbindung zum API-Endpunkt herstelle. Nehmen wir also an, wir haben einen Endpunkt, der die Beiträge ausgibt. Erstellen Sie ein neues Verzeichnis in Ihrem Projekt, ich nenne esservices , und erstellen dann eine Datei mit dem Namen PostsService.js- Inhalt sieht folgendermaßen aus:

import Vue from 'vue'

export default {
  get() {
    return Vue.http.get('/api/posts)
  }
}

Dann gehe ich zu der Komponente, in der ich diesen Dienst verwenden möchte, und importiere ihn

import PostsService from '../services/PostsService'

export default {
  data() {
   return {
     items: []
   }
  },
  created() {
   this.fetchPosts()
  },
  methods: {
   fetchPosts() {
    return PostsService.get()
      .then(response => {
        this.items = response.data
      })
   }
  }
}

Weitere Informationen zu diesem Ansatz finden Sie in meinem Repo auf GitHub unter https://github.com/bedakb/vuewp/tree/master/public/app/themes/vuewp/app


7
Laut Evan You geht Vue-Resource in den Ruhestand und empfiehlt stattdessen Axios. Lesen Sie seinen Artikel Ich mag Ihren Ansatz wirklich, der sich eher wie eckiger 2
anfühlt

@noypee VueResource funktioniert immer noch. Aber egal, was Sie wollen, es wäre genau der gleiche Ansatz mit Axios.
Belmin Bedak

1
Ja, Vue2 wird auch weiterhin Vue-Ressourcen gemäß seinem Artikel aufnehmen
codely

2
Das ist sehr schön, aber wie kann man eine solche Komponente mit mock-PostsService testen?
Shrike

@noypee, vue-resource wird nicht in den Ruhestand versetzt - Evan gab an, dass er ihn lediglich "aus dem offiziellen Empfehlungsstatus zurückzieht" . Er stellte weiter klar, warum sein Team zu dem Schluss kam, dass keine offizielle AJAX-Bibliothek mehr benötigt wird. Der verlinkte Artikel erklärt es gut. Und es sollte beachtet werden, dass die Vue-Ressource immer noch aktiv gepflegt wird und eine absolut praktikable Option ist.
Squidbe

8

Ich schlage vor, einen API-Anbieter zu erstellen, auf den Sie von überall in Ihrer App zugreifen können.

Erstellen Sie einfach einen src/utilsOrdner und darin eine Datei namens api.js.

Exportieren Sie darin Ihren Wrapper, der weiß, wie man mit Ihrer API als Objekt oder als statische ES6-Klasse kommuniziert (ich bevorzuge, wie letztere aussieht und funktioniert, wenn Sie keine Angst vor Klassen haben). Dieser Anbieter kann jede beliebige HTTP-Anforderungsbibliothek verwenden und diese später problemlos austauschen, indem Sie eine einzelne Datei (diese) ändern, anstatt die gesamte Codebasis zu durchsuchen. Hier ist ein Beispiel für die Verwendung von Axios, vorausgesetzt, wir haben eine REST-API zur Verfügung api.example.com/v1, die SSL verwendet:

import axios from 'axios'

import { isProduction, env } from '@/utils/env'

const http = null // not possible to create a private property in JavaScript, so we move it outside of the class, so that it's only accessible within this module

class APIProvider {
  constructor ({ url }) {
    http = axios.create({
      baseURL: url,
       headers: { 'Content-Type': 'application/json' }
    })
  }

  login (token) {
    http.defaults.headers.common.Authorization = `Bearer ${token}`
  }

  logout () {
    http.defaults.headers.common.Authorization = ''
  }

  // REST Methods
  find ({ resource, query }) {
    return http.get(resource, {
      params: query
    })
  }

  get ({ resource, id, query }) {
    return http.get(`${resource}/${id}`, {
      params: query
    })
  }

  create ({ resource, data, query }) {
    return http.post(resource, data, {
      params: query
    })
  }

  update ({ resource, id, data, query }) {
    return http.patch(`${resource}/${id}`, data, {
      params: query
    })
  }

  destroy ({ resource, id }) {
    return http.delete(`${resource}/${id}`)
  }
}

export default new APIProvider({
  url: env('API_URL')  // We assume 'https://api.example.com/v1' is set as the env variable
})

main.jsFühren Sie als Nächstes in Ihrer Datei oder an einem anderen Ort, an dem Sie die Vue-App booten, Folgendes aus:

import api from '@/src/utils/api'

Vue.$api = api

Object.defineProperty(Vue.prototype, '$api', {
  get () {
    return api
  }
})

Jetzt können Sie überall in Ihrer Vue-App darauf zugreifen sowie überall dort, wo Sie Vue selbst importieren:

<template>
  <div class="my-component">My Component</div
</template>

<script>
export default {
  name: 'MyComponent',
  data () {
    return {
      data: []
    }
  },
  async created () {
    const response = await this.$api.find({ resource: 'tasks', query: { page: 2 } })

    this.data = response.data
  }
}
</script>

oder:

// actions.js from Vuex
import Vue from 'vue'

export async function fetchTasks ({ commit }) {
  const response = await Vue.$api.find({ resource: 'tasks', query: { page: 2 } })

  commit('SAVE_TASKS', response.data)

  return response
}

Hoffe das hilft.


3

Ich denke, für Ihre einfache Frage könnte die Antwort jedes ES6-Modul sein, das Funktionen enthält (entspricht Methoden in der Klasse in ANgular) und diese mithilfe von ES6-Importen und -Exporten direkt in Komponenten importiert. Es gibt keine solchen Dienste, die in Komponenten injiziert werden könnten.


1

Sie können Ihren eigenen Dienst erstellen, in dem Sie alle Ihre HTTP-Serveraufrufe tätigen und diese dann in die Komponenten importieren können, in denen Sie sie verwenden möchten.

Verwenden Sie Vuex am besten für komplexe Statusverwaltungsanwendungen, da Sie in Vuex alle asynchronen Aufrufe über Aktionen verarbeiten können, die immer asynchron ausgeführt werden, und die Mutation dann festschreiben, sobald Sie das Ergebnis haben. Die Mutation interagiert direkt mit dem Status und wird aktualisiert es auf unveränderliche Weise (was bevorzugt wird). Dies ist ein zustandsbehafteter Ansatz.

Es gibt auch andere Ansätze. Aber das sind diejenigen, denen ich in meinem Code folge.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.