В моем приложении 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
импортируется/используется, но это не решило проблему.
У меня нет всего вашего кода, но здесь, как я думаю, может случиться. Вы начинаете игру с начальным состоянием, которое вы импортировали. Во время игры вы обновляете состояние объекта, делая что-то вроде:
state.camera['position'] = {
x: 100,
y: 100,
z: 100
}
}
На самом деле происходит то, что ваше начальное состояние было обновлено, потому что у вас есть ссылка на объект, а не на его копию, поэтому при попытке сбросить состояние он остается неизменным, потому что вы случайно изменили исходный объект состояния.
Чтобы решить эту проблему, просто оберните исходное состояние в функцию (фабричную функцию), чтобы всегда возвращалось состояние init:
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()
}
camera: {...initialCameraState}
как для начального состояния, так и для мутации не работало. Я полагаю, что с помощью оператора распространения объекта значения копируются, а не на них ссылаются ...Object.assign
: jsfiddle.net/jrqmvvsz . Так что, честно говоря, я не уверен, что там происходит