Vuex 状态不更新突变
Vuex state not updating on mutation
在我的基于 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
得到 imported/used 的两个地方使用对象展开运算符,但这并没有解决问题。
我没有你的所有代码,但我认为可能会发生这种情况。您正在使用导入的初始状态启动游戏。在游戏过程中,您可以通过执行以下操作来更新对象的状态:
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/
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()
}
在我的基于 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
得到 imported/used 的两个地方使用对象展开运算符,但这并没有解决问题。
我没有你的所有代码,但我认为可能会发生这种情况。您正在使用导入的初始状态启动游戏。在游戏过程中,您可以通过执行以下操作来更新对象的状态:
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/
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()
}