[英]Why does my vuex state change on changing my component level state even if I have not binded the vuex state to any html input element?
I have a vue store which has the following 我有一家vue商店,其中有以下商店
store.js
store.js
import Vue from 'vue'
import Vuex from 'vuex'
const state = {
supplementStore: {}
}
const actions = {
getDataFromApi ({dispatch, commit}) {
APIrunning.then(response => {
commit('SET_SUPPLEMENT', response)
})
}
}
const mutations = {
SET_SUPPLEMENT (state, data) {
state.supplementStore= data
}
}
const foodstore = {
namespaced: true,
state,
actions,
mutations
}
Vue.use(Vuex)
export default new Vuex.Store({
modules: {
foodstore
}
})
My vue component looks like this 我的Vue组件看起来像这样
Supp.vue
Supp.vue
<template>
<input type="checkbox" v-model="supps.logged">
</template>
<script>
import {mapState, mapActions} from 'vuex'
import store from './store'
export default {
data () {
return {
supps: []
}
},
mounted () {
this.supps = this.supplementStore
},
computed: {
...mapState('foodstore', ['supplementStore'])
}
}
</script>
As you can see I have a component level state called supps
which is assigned the value of supplementStore
(which is a vuex state) as soon as it is mounted
. 正如你可以看到我有一个组件级状态称为
supps
被分配的值supplementStore
(这是一个vuex状态),只要它被mounted
。
mounted () {
this.supps = this.supplementStore
},
supplementStore
gets its value from the the API and it is a JSON object which looks like this supplementStore
从API获取其值,并且它是一个JSON对象,看起来像这样
supplementStore = {
logged: true
}
Therefore, when my Supp.vue
component is mounted my local state supps
will become 因此,当我的
Supp.vue
组件安装后,我的本地状态supps
将变为
supps = {
logged: true
}
supps
is binded to an input field of type checkbox (Supp.vue)
using the v-model
directive. supps
使用v-model
指令绑定到类型为checkbox (Supp.vue)
的输入字段。
What I want to achieve:
我要实现的目标:
When I toggle the checkbox, supps.logged
should toggle between true
and false
but, supplementStore.logged
should remain unchanged (since I have not binded it to my input field). 当我切换复选框时,
supps.logged
应该在true
和false
之间切换,但是supplementStore.logged
应该保持不变(因为我尚未将其绑定到我的输入字段)。
What I observe in my
Vue Devtools
:我在
Vue Devtools
观察到的Vue Devtools
:
When I toggle the checkbox, both supps.logged
AND supplementStore.logged
are toggling in sync ie both of them are toggling in sync between true and false, whereas I want only supps.logged
to get toggled. 当我切换复选框时,
supps.logged
和supplementStore.logged
都在同步切换,即它们都在真与假之间同步切换,而我只希望supps.logged
被切换。
Can anyone help me? 谁能帮我?
In Javascript, object is passed by reference. 在Javascript中,对象是通过引用传递的。 (This is a reasonably good explanation => https://medium.com/nodesimplified/javascript-pass-by-value-and-pass-by-reference-in-javascript-fcf10305aa9c )
(这是一个相当不错的解释=> https://medium.com/nodesimplified/javascript-pass-by-value-and-pass-by-reference-in-javascript-fcf10305aa9c )
To avoid this problem, you can clone the object when assigning to supps
. 为避免此问题,可以在分配给
supps
时克隆对象。
mounted () {
this.supps = { ...this.supplementStore } // cloning the object using Javascript Spread syntax
},
Have you tried Object.assign
instead? 您是否尝试过
Object.assign
? In JS objects are passed by reference. 在JS中,对象是通过引用传递的。 Assigning one to a variable will cause the original one to change if the variable is changed inside.
如果在变量内进行更改,则为变量分配一个将导致原始变量更改。
To clone an object, you may try this: 要克隆对象,您可以尝试以下操作:
// this.assignedObj = new object.
// this.obj = original object.
this.assignedObj = Object.assign({}, this.obj);
JSFiddle: https://jsfiddle.net/mr7x4yn0/ JSFiddle: https ://jsfiddle.net/mr7x4yn0/
Edit: As you can see from the demo, Vue.set
or this.$set
will not work for you (probably). 编辑:从演示中可以看到,
Vue.set
或this.$set
对您不起作用(可能)。
The data I was receiving from the API into supplementStore
was in the form of an array of objects: 我从API接收到的数据存储到
supplementStore
是对象数组的形式:
supplementStore = [
{
"logged": true
},
{
"logged": false
}
]
And as Jacob Goh and Yousof K. mentioned in their respective answers that objects and arrays get passed by reference in javascript, I decided to use the following code to assign the value of supplementStore
to supps
inside my mounted()
hook: 正如雅各吴作栋和Yousof K.在对象和数组获得通过javascript参考通过各自的答案中提到,我决定用下面的代码的值赋给
supplementStore
以supps
我里面mounted()
挂钩:
mounted () {
let arr = []
for (let i = 0; i < this.supplementStore.length; i++) {
let obj = Object.assign({}, this.supplementStore[i])
arr.push(obj)
}
this.supps = arr
}
Now when I toggle my checkbox, supplementStore.logged
remains unchanged while supps.logged
toggles between true and false just the way I wanted. 现在,当我切换复选框时,
supplementStore.logged
保持不变,而supps.logged
则按照我想要的方式在true和false之间切换。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.