Quero colocar todas as minhas funções que se comunicam com o servidor e buscam dados em um único arquivo reutilizável no VueJS.
Plugins não parecem ser a melhor alternativa. Molde menos componentes ..?
Quero colocar todas as minhas funções que se comunicam com o servidor e buscam dados em um único arquivo reutilizável no VueJS.
Plugins não parecem ser a melhor alternativa. Molde menos componentes ..?
Respostas:
No total, existem 4 maneiras:
Estou usando axios como cliente HTTP para fazer chamadas API, criei uma gateways
pasta em minha src
pasta e coloquei arquivos para cada backend, criando instâncias de axios , como a seguir
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'
}
})
Agora, em seu componente, você pode ter uma função que buscará dados da API como a seguir:
methods: {
getProducts () {
myApi.get('products?id=' + prodId).then(response => this.product = response.data)
}
}
Como suponho que você queira reutilizar esse método em vários componentes, você pode usar mixins de vue.js:
Mixins são uma maneira flexível de distribuir funcionalidades reutilizáveis para componentes Vue. Um objeto mixin pode conter qualquer opção de componente. Quando um componente usa um mixin, todas as opções do mixin serão “combinadas” com as opções do próprio componente.
Então você pode adicionar um método no mixin e ele estará disponível em todos os componentes, onde o mixin será misturado. Veja o seguinte exemplo:
// 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')
}
})
Estou usando principalmente o recurso Vue.
1. Eu crio um novo arquivo onde faço a conexão com o endpoint da API usando Vue.http.xxx
. Então, digamos que temos um endpoint que produz os posts. Crie um novo diretório em seu projeto, eu o chamo services
e, em seguida, crio o arquivo chamado PostsService.js
- o conteúdo se parece com isto:
import Vue from 'vue'
export default {
get() {
return Vue.http.get('/api/posts)
}
}
Então vou para o componente onde desejo usar este serviço e o 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
})
}
}
}
Para obter mais informações sobre essa abordagem, sinta-se à vontade para verificar meu repositório no GitHub https://github.com/bedakb/vuewp/tree/master/public/app/themes/vuewp/app
Eu sugiro criar um provedor de API que você possa acessar de qualquer lugar em seu aplicativo.
Simplesmente crie uma src/utils
pasta e dentro dela um arquivo chamado api.js
.
Nele, exporte seu wrapper que sabe como se comunicar com sua API como um objeto ou uma classe estática ES6 (eu prefiro como esta última parece e funciona se você não tem medo de classes). Este provedor pode usar qualquer biblioteca de solicitação de HTTP de sua preferência e você pode trocá-la facilmente mais tarde, alterando um único arquivo (este) em vez de procurar por toda a base de código. Aqui está um exemplo de uso de axios, assumindo que temos uma API REST disponível em api.example.com/v1
que usa 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
})
Em seguida, em seu main.js
arquivo ou onde quer que você inicialize o aplicativo Vue, faça o seguinte:
import api from '@/src/utils/api'
Vue.$api = api
Object.defineProperty(Vue.prototype, '$api', {
get () {
return api
}
})
Agora você pode acessá-lo em qualquer lugar em seu aplicativo Vue, bem como em qualquer lugar para importar o próprio Vue:
<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
}
Espero que isto ajude.
Eu acho que para sua pergunta simples, a resposta poderia ser qualquer módulo ES6 contendo funções (equivalente a métodos em classe em ANgular) e importando-as diretamente em componentes usando importações e exportações ES6. Não existem serviços que possam ser injetados em componentes.
Você pode fazer seu próprio serviço onde pode colocar todas as suas chamadas de servidor HTTP e, em seguida, importá-lo para os componentes onde deseja usá-los.
O melhor é usar o Vuex para aplicativos complexos de gerenciamento de estado porque no Vuex você é capaz de lidar com todas as chamadas assíncronas por meio de ações que sempre são executadas de forma assíncrona e, em seguida, confirmar a mutação assim que tiver o resultado. A mutação irá interagir diretamente com o estado e será atualizada de uma maneira imutável (que é preferível). Esta é uma abordagem com estado.
Existem outras abordagens também. Mas esses são os que sigo em meu código.