【问题标题】:Vuex state not updating on mutationVuex 状态未在突变时更新
【发布时间】:2018-05-13 03:18:51
【问题描述】:

在我的基于 Vue.js/Vuex 的应用程序中,我使用这个突变来重置部分 Vuex 状态:

restartGame(state) {
    state.gameRunning = true

    state.camera = {
        position: {
            x: 0,
            y: 10,
            z: 0
        },
        moveForward: false,
        moveBackward: false,
        moveLeft: false,
        moveRight: false,
        velocity: {
            x: 0,
            z: 0
        },
        mouseMovement: {
            x: 0,
            y: 0
        },
        rotation: {
            x: 0,
            y: 0
        }
    }
}

这样,一切正常,但写出整个相机状态对我来说似乎很冗长。所以我将初始相机状态提取到一个单独的文件中:

initialCameraState.js

export default {
    position: {
        x: 0,
        y: 10,
        z: 0
    },
    moveForward: false,
    moveBackward: false,
    moveLeft: false,
    moveRight: false,
    velocity: {
        x: 0,
        z: 0
    },
    mouseMovement: {
        x: 0,
        y: 0
    },
    rotation: {
        x: 0,
        y: 0
    }
}

我已经像这样重构了 resetGame() 突变:

import initialCameraState from './initialCameraState'

restartGame(state) {
    state.gameRunning = true

    state.camera = initialCameraState
}

但不知何故,这不起作用,Vuex 商店没有更新,但似乎保持不变。这怎么可能?

我还使用initialCameraState.js 设置(部分)Vuex 商店的初始状态。我的第一个想法是,当改变状态的相应部分时,initialCameraState 也被改变了。这可以解释resetGame() 没有显示任何效果。所以我尝试在 initialCameraState.js 被导入/使用的两个地方都使用对象扩展运算符,但这并没有解决问题。

【问题讨论】:

    标签: javascript vue.js vuex


    【解决方案1】:

    我没有你所有的代码,但这是我认为可能发生的事情。您正在使用您导入的初始状态启动游戏。在游戏过程中,您可以通过以下方式更新对象的状态:

       state.camera['position'] = {
          x: 100,
          y: 100,
          z: 100
        }
      }
    

    实际发生的情况是您的初始状态已更新,因为您有对对象的引用,而不是它的副本,因此当您尝试重置状态时,它只是保持不变,因为您无意中更改了初始状态状态对象。

    要解决这个问题,只需将初始状态包装在一个函数(工厂函数)中,以便始终返回初始状态:

    export default function() {
      return {    
        position: {
          x: 0,
          y: 10,
          z: 0
        },
        moveForward: false,
        moveBackward: false,
        moveLeft: false,
        moveRight: false,
        velocity: {
          x: 0,
          z: 0
        },
        mouseMovement: {
          x: 0,
          y: 0
        },
        rotation: {
          x: 0,
          y: 0
        }
      }
    };
    

    这是一个 JSFiddle,展示了没有函数时会发生什么(位置保持不变):https://jsfiddle.net/9qg8ws0x/

    这里有一个功能(位置被重置):https://jsfiddle.net/27xozazf/

    【讨论】:

    • 您的解决方案有效!但我仍然很好奇为什么将camera: {...initialCameraState} 用于初始状态和突变都不起作用。我认为使用对象扩展运算符,值被复制,而不是被引用......
    • @lysigk 从理论上讲,扩展运算符应该克隆对象,它适用于 Object.assign:jsfiddle.net/jrqmvvsz。所以,老实说,我不确定那里发生了什么
    【解决方案2】:
    export default {
      initializeCamera () {
        return {
          position: {
            x: 0,
            y: 10,
            z: 0
          },
          moveForward: false,
          moveBackward: false,
          moveLeft: false,
          moveRight: false,
          velocity: {
            x: 0,
            z: 0
          },
          mouseMovement: {
            x: 0,
            y: 0
          },
          rotation: {
            x: 0,
            y: 0
          }
        }
      }
    }
    
    import initial from './initial'
    
    restartGame(state) {
      state.gameRunning = true
      state.camera = initial.initializeCamera()
    }
    

    【讨论】:

      猜你喜欢
      • 2020-12-18
      • 2019-11-30
      • 2019-07-26
      • 2017-05-20
      • 2019-08-17
      • 2020-09-10
      • 1970-01-01
      • 2019-09-27
      • 2019-10-12
      相关资源
      最近更新 更多