service - mixin - vuejs helpers
¿Cuál es el equivalente del servicio angular en VueJS? (6)
Quiero poner todas mis funciones que se comunican con el servidor y obtienen datos en un solo archivo reutilizable en VueJS.
Los complementos no parecen ser la mejor alternativa. Plantilla menos componentes ..?
Creo que para su simple pregunta, la respuesta podría ser cualquier módulo ES6 que contenga funciones (equivalentes a los métodos en clase en ANgular) e importarlas directamente en componentes utilizando las importaciones y exportaciones ES6. No existen tales servicios que podrían inyectarse en los componentes.
En total hay 4 formas:
- Servicio sin estado: entonces debes usar mixins
- Servicio con estado: use Vuex
- Servicio de exportación e importación desde un código vue
- cualquier objeto global javascript
Estoy usando
axios
como cliente HTTP para hacer llamadas api, he creado una carpeta
gateways
en mi carpeta
src
y he puesto archivos para cada back-end, creando
instancias axios
, como las siguientes
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''
}
})
Ahora en su componente, puede tener una función que obtendrá datos de la API de la siguiente manera:
methods: {
getProducts () {
myApi.get(''products?id='' + prodId).then(response => this.product = response.data)
}
}
Como supongo que desea reutilizar este método en múltiples componentes, puede usar mixins de vue.js:
Las mixinas son una forma flexible de distribuir funcionalidades reutilizables para componentes Vue. Un objeto mixin puede contener cualquier opción de componente. Cuando un componente utiliza un mixin, todas las opciones en el mixin se "mezclarán" en las propias opciones del componente.
Por lo tanto, puede agregar un método en mixin y estará disponible en todos los componentes, donde se mezclará mixin. Ver el siguiente ejemplo:
// 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'')
}
})
Estoy usando Vue Resource principalmente.
1.Creo un nuevo archivo donde hago la conexión al punto final de la API usando
Vue.http.xxx
. Así que digamos que tenemos un punto final que genera las publicaciones. Crea un nuevo directorio en tu proyecto, lo llamo
services
y luego creo un archivo llamado
PostsService.js
: el contenido se ve así:
import Vue from ''vue''
export default {
get() {
return Vue.http.get(''/api/posts)
}
}
Luego voy al componente donde quiero usar este servicio, y 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
})
}
}
}
Para obtener más información sobre este enfoque, no dude en consultar mi repositorio en GitHub https://github.com/bedakb/vuewp/tree/master/public/app/themes/vuewp/app
Puede hacer su propio servicio donde puede colocar todas las llamadas de su servidor HTTP y luego importarlas a los componentes donde desea usarlas.
Lo mejor es utilizar Vuex para aplicaciones de administración de estado complejas porque en Vuex puede manejar todas las llamadas asíncronas a través de acciones que siempre se ejecutan de forma asincrónica y luego confirmar la mutación una vez que tenga el resultado. La mutación interactuará directamente con el estado y se actualizará de manera inmutable (lo cual es preferible). Este es un enfoque con estado.
También hay otros enfoques. Pero estos son los que sigo en mi código.
Sugiero crear un proveedor de API al que pueda acceder desde cualquier lugar de su aplicación.
Simplemente cree una carpeta
src/utils
y dentro de ella un archivo llamado
api.js
En él, exporte su contenedor que sepa cómo comunicarse con su API como un objeto o una clase estática ES6 (prefiero cómo se ve y funciona este último si no tiene miedo a las clases).
Este proveedor puede usar cualquier biblioteca de solicitud HTTP que desee y puede intercambiarla fácilmente más tarde cambiando un solo archivo (este) en lugar de buscar toda la base de código.
Aquí hay un ejemplo del uso de axios, suponiendo que tengamos una API REST disponible en
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
})
A continuación, en su archivo
main.js
o en cualquier otro lugar donde
main.js
la aplicación Vue, haga lo siguiente:
import api from ''@/src/utils/api''
Vue.$api = api
Object.defineProperty(Vue.prototype, ''$api'', {
get () {
return api
}
})
Ahora puede acceder a él desde cualquier lugar de su aplicación Vue, así como desde cualquier lugar donde importe 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>
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
}
Espero que esto ayude.