为什么即使我没有将 vuex 状态绑定到任何 html 输入元素,我的 vuex 状态也会随着组件级状态的改变而改变?
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?
我有一个 vue 商店,其中包含以下内容
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
}
})
我的 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>
如您所见,我有一个名为 supps
的组件级状态,一旦它是 mounted
,它就会被分配 supplementStore
的值(这是一个 vuex 状态)。
mounted () {
this.supps = this.supplementStore
},
supplementStore
从 API 获取它的值,它是一个 JSON 对象,看起来像这样
supplementStore = {
logged: true
}
因此,当我的 Supp.vue
组件被安装时,我的本地状态 supps
将变为
supps = {
logged: true
}
supps
使用 v-model
指令绑定到类型为复选框 (Supp.vue)
的输入字段。
What I want to achieve:
当我切换复选框时,supps.logged
应该在 true
和 false
之间切换,但是 supplementStore.logged
应该保持不变(因为我没有将它绑定到我的输入场)。
What I observe in my Vue Devtools
:
当我切换复选框时,supps.logged
和 supplementStore.logged
都同步切换,即它们都在 true 和 false 之间同步切换,而我只想 supps.logged
切换。
谁能帮帮我?
在Javascript中,对象通过引用传递。 (这是一个相当不错的解释=> https://medium.com/nodesimplified/javascript-pass-by-value-and-pass-by-reference-in-javascript-fcf10305aa9c)
为避免此问题,您可以在分配给 supps
时克隆对象。
mounted () {
this.supps = { ...this.supplementStore } // cloning the object using Javascript Spread syntax
},
您尝试过 Object.assign
吗?在 JS 中,对象是通过引用传递的。给一个变量赋值,如果变量里面改了,原来的也会变。
要克隆一个对象,你可以试试这个:
// this.assignedObj = new object.
// this.obj = original object.
this.assignedObj = Object.assign({}, this.obj);
JSFiddle:https://jsfiddle.net/mr7x4yn0/
编辑:从演示中可以看出,Vue.set
或 this.$set
对您不起作用(可能)。
我从 API 接收到 supplementStore
的数据采用对象数组的形式:
supplementStore = [
{
"logged": true
},
{
"logged": false
}
]
正如 Jacob Goh 和 Yousof K. 在各自的回答中提到的,对象和数组在 javascript 中通过引用传递,我决定使用以下代码来分配 supplementStore
的值在我的 mounted()
挂钩中 supps
:
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
}
现在,当我切换复选框时,supplementStore.logged
保持不变,而 supps.logged
按照我想要的方式在 true 和 false 之间切换。
我有一个 vue 商店,其中包含以下内容
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
}
})
我的 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>
如您所见,我有一个名为 supps
的组件级状态,一旦它是 mounted
,它就会被分配 supplementStore
的值(这是一个 vuex 状态)。
mounted () {
this.supps = this.supplementStore
},
supplementStore
从 API 获取它的值,它是一个 JSON 对象,看起来像这样
supplementStore = {
logged: true
}
因此,当我的 Supp.vue
组件被安装时,我的本地状态 supps
将变为
supps = {
logged: true
}
supps
使用 v-model
指令绑定到类型为复选框 (Supp.vue)
的输入字段。
What I want to achieve:
当我切换复选框时,supps.logged
应该在 true
和 false
之间切换,但是 supplementStore.logged
应该保持不变(因为我没有将它绑定到我的输入场)。
What I observe in my
Vue Devtools
:
当我切换复选框时,supps.logged
和 supplementStore.logged
都同步切换,即它们都在 true 和 false 之间同步切换,而我只想 supps.logged
切换。
谁能帮帮我?
在Javascript中,对象通过引用传递。 (这是一个相当不错的解释=> https://medium.com/nodesimplified/javascript-pass-by-value-and-pass-by-reference-in-javascript-fcf10305aa9c)
为避免此问题,您可以在分配给 supps
时克隆对象。
mounted () {
this.supps = { ...this.supplementStore } // cloning the object using Javascript Spread syntax
},
您尝试过 Object.assign
吗?在 JS 中,对象是通过引用传递的。给一个变量赋值,如果变量里面改了,原来的也会变。
要克隆一个对象,你可以试试这个:
// this.assignedObj = new object.
// this.obj = original object.
this.assignedObj = Object.assign({}, this.obj);
JSFiddle:https://jsfiddle.net/mr7x4yn0/
编辑:从演示中可以看出,Vue.set
或 this.$set
对您不起作用(可能)。
我从 API 接收到 supplementStore
的数据采用对象数组的形式:
supplementStore = [
{
"logged": true
},
{
"logged": false
}
]
正如 Jacob Goh 和 Yousof K. 在各自的回答中提到的,对象和数组在 javascript 中通过引用传递,我决定使用以下代码来分配 supplementStore
的值在我的 mounted()
挂钩中 supps
:
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
}
现在,当我切换复选框时,supplementStore.logged
保持不变,而 supps.logged
按照我想要的方式在 true 和 false 之间切换。