Qual è l'equivalente del servizio angolare in VueJS?


95

Voglio mettere tutte le mie funzioni che parlano al server e recuperare i dati in un unico file riutilizzabile in VueJS.

I plugin non sembrano essere la migliore alternativa. Template meno componenti ..?

Risposte:


58

In totale ci sono 4 modi:

  • Servizio apolidi: allora dovresti usare i mixin
  • Servizio stateful: usa Vuex
  • Servizio di esportazione e importazione da un codice vue
  • qualsiasi oggetto globale javascript

4
Sembra molto imbarazzante cercare di aderire alle stranezze di Vuex di chiamare metodi con stringhe letterali per i servizi quando potresti creare una classe TypeScript / JS che contiene lo stato e la logica per esso? Come puoi utilizzare una classe con stato come servizio all'interno di Vue?
Douglas Gaskell

37

Sto usando axios come client HTTP per effettuare chiamate api, ho creato una gatewayscartella nella mia srccartella e ho inserito file per ogni backend, creando istanze di axios , come segue

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'
  }
})

Ora nel tuo componente, puoi avere una funzione che recupera i dati dall'API come segue:

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

Poiché presumo che tu voglia riutilizzare questo metodo in più componenti, puoi usare i mixin di vue.js:

I mixin sono un modo flessibile per distribuire funzionalità riutilizzabili per i componenti Vue. Un oggetto mixin può contenere qualsiasi opzione componente. Quando un componente utilizza un mixin, tutte le opzioni nel mixin verranno "miscelate" nelle opzioni proprie del componente.

Quindi puoi aggiungere un metodo in mixin e sarà disponibile in tutti i componenti, dove il mixin verrà miscelato. Vedere il seguente esempio:

// 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
come aggiornerete X-Auth-Token di myApi.js quando l'utente accederà
Amarjit Singh

3
di solito questo non è un valore statico
Amarjit Singh

30

Sto usando principalmente Vue Resource.

1. Creo un nuovo file in cui Vue.http.xxxeseguo la connessione all'endpoint API utilizzando .Quindi diciamo che abbiamo un endpoint che emette i post.Crea una nuova directory nel tuo progetto, lo chiamo servicese quindi creo il file chiamato PostsService.js- il contenuto ha questo aspetto:

import Vue from 'vue'

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

Quindi vado al componente in cui desidero utilizzare questo servizio e lo importo

import PostsService from '../services/PostsService'

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

Per maggiori informazioni su questo approccio, sentiti libero di controllare il mio repository su GitHub https://github.com/bedakb/vuewp/tree/master/public/app/themes/vuewp/app


7
Secondo Evan You, Vue-Resource andrà in pensione e consiglia invece Axios. Leggi il suo articolo Mi piace molto il tuo approccio che sembra più angolare 2
codely

@noypee VueResource funziona ancora, ma non importa usare quello che vuoi, sarebbe esattamente lo stesso approccio con Axios.
Belmin Bedak

1
Sì, Vue2 continuerà a ospitare anche vue-resource secondo il suo articolo
codely

2
Questo è molto carino, ma come testare un componente del genere con mock-PostsService?
Shrike

@noypee, vue-resource non verrà ritirato - Evan ha dichiarato che lo sta semplicemente "ritirando dallo stato di raccomandazione ufficiale" . Ha ulteriormente chiarito perché il suo team ha concluso che non c'era più bisogno di una libreria AJAX ufficiale. L'articolo collegato lo spiega bene. E va notato che vue-resource è ancora attivamente mantenuto ed è un'opzione perfettamente praticabile.
squidbe

8

Suggerisco di creare un provider API a cui puoi accedere da qualsiasi punto della tua app.

Basta creare una src/utilscartella e al suo interno un file chiamatoapi.js .

In esso, esporta il tuo wrapper che sa come comunicare con la tua API come un oggetto o una classe statica ES6 (preferisco l'aspetto e il funzionamento di quest'ultima se non hai paura delle classi). Questo provider può utilizzare qualsiasi libreria di richieste HTTP che ti piace e puoi facilmente sostituirla in seguito modificando un singolo file (questo) invece di cercare l'intera base di codice. Ecco un esempio di utilizzo di axios, supponendo di avere a disposizione un'API REST api.example.com/v1che utilizza SSL:

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

Successivamente, nel tuo main.jsfile o in qualsiasi altro punto in cui esegui il bootstrap dell'app Vue, procedi come segue:

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

Vue.$api = api

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

Ora puoi accedervi ovunque nella tua app Vue e ovunque importi Vue stesso:

<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>

o:

// 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
}

Spero che questo ti aiuti.


3

Penso che per la tua semplice domanda la risposta potrebbe essere qualsiasi modulo ES6 contenente funzioni (equivalenti ai metodi in classe in ANgular) e importandole direttamente nei componenti utilizzando ES6 importa ed esporta. Non esistono servizi di questo tipo che potrebbero essere iniettati nei componenti.


1

È possibile creare il proprio servizio in cui è possibile inserire tutte le chiamate del server HTTP e quindi importarlo nei componenti in cui si desidera utilizzarli.

La cosa migliore è utilizzare Vuex per complesse applicazioni di gestione dello stato perché in Vuex puoi gestire tutte le chiamate asincrone tramite azioni che vengono sempre eseguite in modo asincrono e quindi eseguire il commit della mutazione una volta ottenuto il risultato. La mutazione interagirà direttamente con lo stato e si aggiornerà in un modo immutabile (che è preferito). Questo è un approccio stateful.

Ci sono anche altri approcci. Ma questi sono quelli che seguo nel mio codice.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.