Vuex 全局状态更改不会触发 Nuxt 中 v-for 循环中的重新渲染组件

Posted

技术标签:

【中文标题】Vuex 全局状态更改不会触发 Nuxt 中 v-for 循环中的重新渲染组件【英文标题】:Vuex global state change does not trigger re-render component in v-for loop in Nuxt 【发布时间】:2022-01-18 13:24:56 【问题描述】:

我很难在 Vue.js 中将 vuex 全局状态与重新渲染子组件结合使用。 全局状态已发生变异,但不会在 v-for 循环中重新渲染其数据。

所有数据列表都被渲染了,但是当新数据发生变化时,/blog中的组件并没有改变其中的数据。

这是一些代码:

/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)
  ,

/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,
    )
  ,
,

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

【问题讨论】:

您能否使用您的 vue 开发工具检查您的状态并检查您是否未进入 those caveats? 奇怪的是“Object.assign(item, payload);”即使分配“state.allData = payload”也不会触发反应。它似乎与 redux react 完全不同。 是的,可能是因为它是 Vuex。在这里,你 Object.assign 到一个局部变量而不是状态。你到底想做什么? vuex.vuejs.org/guide/mutations.html#commit-with-payload @kissu 我只想更改 allData 数组中的 1 个元素。当我使用state.allData.splice(payload.index, 1, Object.assign(state.allData[payload.index], payload)) 时,它有效,但不确定它是否是最佳解决方案。 【参考方案1】:

这是一个关于如何使用 Vuex 并将数据有效地加载到 Nuxt 应用程序的完整示例(主观但使用良好实践)。

/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 )
  ,

【讨论】:

以上是关于Vuex 全局状态更改不会触发 Nuxt 中 v-for 循环中的重新渲染组件的主要内容,如果未能解决你的问题,请参考以下文章

错误:[vuex] 不要在突变处理程序之外改变 vuex 存储状态。 NUXT

v-on:click 永远不会触发 Nuxt 组件中的按钮,因为中间件

使用 Lodash.remove 通过 Vuex 突变更改状态不会触发我的 Vue 组件中的反应式重新渲染

突变未提交状态 vuex - Nuxt

Vue 2 和 Nuxt:v-for 中的变量 href(Vuex 状态变量)

Vue3 Vuex状态更改不更新计算值