vue.js - tutorial - Vuex representa los datos que se obtienen de la API REST
vuex store (2)
En mi experiencia, puede omitir algunas comprobaciones si preestablece el estado con un valor vacío del mismo tipo que el resultado esperado (si sabe qué esperar, por supuesto), por ejemplo, si tiene una matriz de elementos, comience con []
lugar de null
ya que no romperá v-for
directivas v-for
, .length
y los intentos de acceso a datos similares.
Pero en general, agregar v-if
es algo muy normal de hacer. Hay una sección sobre esto en la documentación del vue-router
y verificar si las propiedades existen o no es exactamente lo que sugiere. Otra solución posible que menciona es obtener datos dentro de beforeRouteEnter
, lo que asegura que siempre beforeRouteEnter
al componente con tus datos ya disponibles.
En última instancia, ambas soluciones son correctas, y la decisión entre ellas es más una pregunta UX / UI.
Para tal componente
<template>
<div>
<router-link :to="{name:''section'', params: { sectionId: firstSectionId }}">Start</router-link>
</div>
</template>
<script lang="ts">
import { mapActions } from "vuex"
export default {
mounted() {
this.getSectionId()
},
computed: {
firstSectionId() {
return this.$store.state.firstSectionId
}
},
methods: mapActions(["getSectionId"])
}
</script>
Almacenar:
const store: any = new Vuex.Store({
state: {
firstSectionId: null
},
// actions,
// mutations
})
Tengo una solicitud web en la acción getSectionId
y está getSectionId
datos de forma asincrónica y llama a una mutación que llenará firstSectionId
en estado. Durante la renderización inicial firstSectionId
es nulo y recibo la advertencia de que falta el parámetro requerido durante la prestación del router-link
.
Aquí no es un problema agregar v-if="firstSectionId"
. Pero, en general, ¿cuál es el enfoque para obtener datos de un servidor para su visualización? Actualmente, todos mis componentes comprueban si hay datos presentes en la tienda antes del procesamiento, ¿es normal o hay una mejor manera de esperar la carga de datos antes de representarlo?
Un enfoque para obtener datos de forma asíncrona es usar la promesa en las acciones de vuex store.
Vue.http.get(API_URL)
.then((response) => {
//use response object
})
.catch((error => {
console.log(error.statusText)
}))
Para demostrar que hago una solicitud a esta ruta . Puedes ver cómo debería ser la respuesta. Vamos a guardar el objeto de respuesta en la matriz state.users.
store.js
const store = new Vuex.Store({
state: {
users: []
},
mutations: {
FETCH_USERS(state, users) {
state.users = users
}
},
actions: {
fetchUsers({ commit }, { self }) {
Vue.http.get("https://jsonplaceholder.typicode.com/users")
.then((response) => {
commit("FETCH_USERS", response.body);
self.filterUsers();
})
.catch((error => {
console.log(error.statusText)
}))
}
}
})
export default store
self.filteruser()
que hay un método self.filteruser()
después de la confirmación. Ese es un momento crucial. Antes de eso estamos cometiendo una mutación , que es una operación sincrónica y estamos seguros de que tendremos nuestra respuesta en la tienda. Estado que se puede usar en el método filterUsers()
(no olvides pasar el auto parm)
Users.vue
import store from "../store/store"
export default {
name: ''users'',
created() {
this.$store.dispatch("fetchUsers", { self: this })
},
methods:{
filterUsers() {
//do something with users
console.log("Users--->",this.$store.state.users)
}
}
}
Mejores formas (ES6 y ES7)
ES6 Promesas para la programación asincrónica
//User.vue
created() {
this.$store.dispatch("fetchUser").then(() => {
console.log("This would be printed after dispatch!!")
})
}
//store.js
actions: {
fetchUser({ commit }) {
return new Promise((resolve, reject) => {
Vue.http.get("https://jsonplaceholder.typicode.com/users")
.then((response) => {
commit("FETCH_USERS", response.body);
resolve();
})
.catch((error => {
console.log(error.statusText);
}));
});
}
}
ES7: async / await
Para alejarse del infierno de devolución de llamada, y para mejorar la programación asincrónica, use la función async
, y puede await
una promesa. El código parece mucho más fácil de seguir (como si fuera síncrono), pero el código no es legible para los navegadores, por lo que necesitarás que Babel Transpiler lo ejecute.
actions: {
async actionA ({ commit }) {
commit(''gotData'', await getData())
},
async actionB ({ dispatch, commit }) {
await dispatch(''actionA'') // wait for actionA to finish
commit(''gotOtherData'', await getOtherData())
}
}