Tengo dificultades para usar vuex global state combine con volver a renderizar el componente secundario en Vue.js. El estado global está mutado pero no vuelve a representar sus datos en el bucle v-for.
Se representa toda la lista de datos, pero cuando los nuevos datos cambian, el componente en /blog no cambia los datos en él.
Aquí hay algo de código:
/store/index.js
export const state = () => ({ allData: [], }) export const getters = { getAllData: (state) => state.allData, } export const mutations = { GET_DATAS(state, payload) { state.allData = payload }, UPDATE_DATA(state, payload) { const item = state.allData[payload.index] Object.assign(item, payload) }, } export const actions = { getDatas({ commit, state }, payload) { return fetch(`URL_FETCH`) .then((data) => data.json()) .then((data) => { commit('GET_DATAS', data) }) .catch((err) => console.log(err)) }, updateData({ commit, state }, payload) { commit('UPDATE_DATA', payload) }, } en /layouts/default.vue
beforeCreate() { this.$store.dispatch('getDatas').then(() => { connectSocket() }) }, methods: { connectSocket() { // connect & received message from socket // received message from socket this.$root.$emit('updateData', { index: 12, price: 34, change: 56, percent: 78, }) }, }, y en /pages/blog/index.vue
<template> <div> <div v-for="index in getAllData" :key="index.name" class="w-100 grid-wrapper" > <div>{{ index.price }}</div> <div>{{ index.change }}</div> <div>{{ index.percent }}</div> </div> </div> </template> <script> import { mapGetters } from 'vuex' export default { data() { return {} }, computed: { ...mapGetters(['getAllData']), }, mounted() { this.$root.$on('updateData', (item) => { this.$store.dispatch('updateData', { index: item.index, price: item.price, percent: item.percent, change: item.change, }) }) }, } </script>Aquí hay un ejemplo completo sobre cómo usar Vuex y cargar los datos de manera eficiente en una aplicación Nuxt (subjetivo pero usando buenas prácticas).
/pages/index.vue
<template> <div> <main v-if="!$fetchState.pending"> <div v-for="user in allData" :key="user.id" style="padding: 0.5rem 0"> <span>{{ user.email }}</span> </div> </main> <button @click="fakeUpdate">Update the 2nd user</button> </div> </template> <script> import { mapState, mapActions } from 'vuex' export default { data() { return { mockedData: { name: 'John Doe', username: 'jodoe', email: 'yoloswag@gmail.com', phone: '1-770-736-8031 x56442', website: 'hildegard.org', }, } }, async fetch() { await this.setAllData() }, computed: { ...mapState(['allData']), }, methods: { ...mapActions(['setAllData', 'updateData']), fakeUpdate() { this.updateData({ index: 1, payload: this.mockedData }) }, }, } </script> /store/index.js
import Vue from 'vue' export const state = () => ({ allData: [], }) export const mutations = { SET_ALL_DATA(state, payload) { state.allData = payload }, UPDATE_SPECIFIC_DATA(state, { index, payload }) { Vue.set(state.allData, index, payload) }, } export const actions = { async setAllData({ commit }) { try { const httpCall = await fetch('https://jsonplaceholder.typicode.com/users') const response = await httpCall.json() commit('SET_ALL_DATA', response) } catch (e) { console.warn('error >>', e) } }, updateData({ commit }, { index, payload }) { commit('UPDATE_SPECIFIC_DATA', { index, payload }) }, }