Quel est l'équivalent du service angulaire dans VueJS?


95

Je veux mettre toutes mes fonctions qui parlent au serveur et récupèrent les données dans un seul fichier réutilisable dans VueJS.

Les plugins ne semblent pas être la meilleure alternative. Modèle moins de composants ..?

Réponses:


58

Au total, il y a 4 façons:

  • Service sans état: alors vous devriez utiliser des mixins
  • Service avec état: utilisez Vuex
  • Exporter le service et importer à partir d'un code de vue
  • tout objet global javascript

4
Il semble très gênant d'essayer de respecter les bizarreries de Vuex d'appeler des méthodes avec des chaînes littérales pour les services alors que vous pourriez créer une classe TypeScript / JS qui contient l'état et la logique pour cela? Comment pouvez-vous utiliser une classe avec état en tant que service dans Vue?
Douglas Gaskell

37

J'utilise axios comme client HTTP pour passer des appels api, j'ai créé un gatewaysdossier dans mon srcdossier et j'ai mis des fichiers pour chaque backend, créant des instances axios , comme suit

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

Maintenant dans votre composant, vous pouvez avoir une fonction qui récupérera les données de l'API comme suit:

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

Comme je suppose que vous souhaitez réutiliser cette méthode dans plusieurs composants, vous pouvez utiliser des mixins de vue.js:

Les mixins sont un moyen flexible de distribuer des fonctionnalités réutilisables pour les composants Vue. Un objet mixin peut contenir toutes les options de composant. Lorsqu'un composant utilise un mixin, toutes les options du mixin seront «mélangées» dans les propres options du composant.

Vous pouvez donc ajouter une méthode dans mixin et elle sera disponible dans tous les composants, où mixin sera mélangé. Voir l'exemple suivant:

// 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
comment allez-vous mettre à jour X-Auth-Token de myApi.js lorsque l'utilisateur se connectera
Amarjit Singh

3
généralement ce n'est pas une valeur statique
Amarjit Singh

30

J'utilise principalement Vue Resource.

1.Je crée un nouveau fichier où je me connecte au point de terminaison de l'API en utilisant Vue.http.xxx.Donc disons que nous avons un point de terminaison qui génère les messages.Créez un nouveau répertoire dans votre projet, je l'appelle services, puis créez le fichier appelé PostsService.js- le contenu ressemble à ceci:

import Vue from 'vue'

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

Ensuite, je vais au composant où je veux utiliser ce service, et je l'importe

import PostsService from '../services/PostsService'

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

Pour plus d'informations sur cette approche, n'hésitez pas à consulter mon dépôt sur GitHub https://github.com/bedakb/vuewp/tree/master/public/app/themes/vuewp/app


7
Selon Evan You, Vue-Resource prendra sa retraite et recommande Axios à la place. Lire son article J'aime beaucoup votre approche qui ressemble plus à angulaire 2
codely

@noypee VueResource fonctionne toujours, mais peu importe ce que vous voulez, ce serait exactement la même approche avec Axios.
Belmin Bedak

1
Oui, Vue2 continuera à accueillir vue-resource également selon son article
codely

2
C'est très sympa mais comment tester un tel composant avec mock-PostsService?
Shrike

@noypee, vue-resource n'est pas en train d'être retiré - Evan a déclaré qu'il "le retirait simplement du statut de recommandation officielle" . Il a en outre précisé pourquoi son équipe avait conclu qu'il n'y avait plus besoin d'une bibliothèque officielle AJAX. L'article lié l'explique bien. Et il convient de noter que vue-resource est toujours activement maintenu et une option parfaitement viable.
squidbe

8

Je suggère de créer un fournisseur d'API auquel vous pouvez accéder de n'importe où dans votre application.

Créez simplement un src/utilsdossier et à l'intérieur de celui-ci un fichier appeléapi.js .

Dans celui-ci, exportez votre wrapper qui sait comment communiquer avec votre API en tant qu'objet ou classe statique ES6 (je préfère à quoi cette dernière ressemble et fonctionne si vous n'avez pas peur des classes). Ce fournisseur peut utiliser n'importe quelle bibliothèque de requêtes HTTP que vous aimez et vous pouvez facilement l'échanger plus tard en modifiant un seul fichier (celui-ci) au lieu de rechercher toute la base de code. Voici un exemple d'utilisation d'axios, en supposant que nous ayons une API REST disponible à api.example.com/v1qui utilise 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
})

Ensuite, dans votre main.jsfichier ou partout où vous démarrez l'application Vue, procédez comme suit:

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

Vue.$api = api

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

Vous pouvez maintenant y accéder n'importe où dans votre application Vue ainsi que partout où vous importez Vue elle-même:

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

ou:

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

J'espère que cela t'aides.


3

Je pense que pour votre question simple, la réponse pourrait être n'importe quel module ES6 contenant des fonctions (équivalentes aux méthodes de classe dans ANgular) et les importer directement dans des composants à l'aide d'importations et d'exportations ES6. Il n'y a pas de tels services qui pourraient être injectés dans les composants.


1

Vous pouvez créer votre propre service où vous pouvez passer tous vos appels de serveur HTTP, puis les importer dans les composants où vous souhaitez les utiliser.

Le mieux est d'utiliser Vuex pour des applications de gestion d'état complexes car dans Vuex, vous êtes capable de gérer tous les appels asynchrones via des actions qui s'exécutent toujours de manière asynchrone, puis de valider la mutation une fois que vous avez le résultat. de manière immuable (ce qui est préféré). C'est une approche avec état.

Il existe également d'autres approches. Mais ce sont ceux que je suis dans mon code.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.