如何在 Vuex 中正确混合和隔离对象
How to correctly mix and isolate objects in Vuex
我正在尝试使用模块为 Vuex 创建一种 mixin,但动作在模块中混合:
这是子事件模块:
import Form from '../../classes/Form'
import * as mutationsMixin from './mixins/mutations.js'
import * as actionsMixin from './mixins/actions.js'
import * as statesMixin from './mixins/states.js'
const state = merge_objects(statesMixin.common, {
data: {},
event: null,
form: new Form({
name: null,
}),
})
const actions = merge_objects(actionsMixin, {
select() {
dd('subevent select')
},
})
const mutations = merge_objects(mutationsMixin, {
mutateSetEvent(state, payload) {
state.event = payload
},
})
dd('subEvents')
export default {
state,
actions,
mutations,
}
这是商店
/**
* Imports
*/
import Vue from 'vue'
import Vuex from 'vuex'
/**
* Vuex
*/
Vue.use(Vuex)
/**
* Global state
*/
import * as actions from './actions'
import * as getters from './getters'
import * as mutations from './mutations'
/**
* Modules
*/
import gate from './modules/gate'
import events from './modules/events'
import subEvents from './modules/subEvents'
import categories from './modules/categories'
import people from './modules/people'
import roles from './modules/roles'
import institutions from './modules/institutions'
import environment from './modules/environment'
/**
* State
*/
const state = {
mounted: false,
}
/**
* Store
*/
let store = new Vuex.Store({
state,
actions,
getters,
mutations,
modules: {
events,
people,
categories,
environment,
subEvents,
gate,
roles,
institutions,
},
})
store.dispatch('environment/absorbLaravel')
export default store
这是 merge_object 助手:
window.merge_objects = (target, ...sources) => {
return Object.assign(target, ...sources)
}
因此,如果您查看商店导入,您会看到子事件是在事件之后加载的,并且上面的子事件商店中的操作 select()(最初来自 mixin)正在加载超载,但是当我调用未超载的 events/select() 时,我在控制台中收到 'subevent select' 消息(dd() 是一个帮助程序)
这张图片稍微解释一下
问题是 Object.assign
没有创建副本,而是修改了作为第一个参数传递给它的对象。该函数将 return 第一个对象。
const a = {};
Object.assign(a, { a: 1 });
console.log(a); // { a: 1 }
在你的情况下,我认为你不需要对象的深度克隆。您只是不想直接修改 mixin。如果您使用新创建的对象作为第一个参数调用 Object.assign
,您将对下一个参数中的所有对象进行浅表复制。
Object.assign({}, target, ...sources)
const a = {};
Object.assign({}, a, { a: 1 });
console.log(a); // {}
如果您需要深度克隆(例如,因为您的对象中有您不想在实例之间共享的嵌套对象,我建议您使用 lodash.merge
.
我正在尝试使用模块为 Vuex 创建一种 mixin,但动作在模块中混合:
这是子事件模块:
import Form from '../../classes/Form'
import * as mutationsMixin from './mixins/mutations.js'
import * as actionsMixin from './mixins/actions.js'
import * as statesMixin from './mixins/states.js'
const state = merge_objects(statesMixin.common, {
data: {},
event: null,
form: new Form({
name: null,
}),
})
const actions = merge_objects(actionsMixin, {
select() {
dd('subevent select')
},
})
const mutations = merge_objects(mutationsMixin, {
mutateSetEvent(state, payload) {
state.event = payload
},
})
dd('subEvents')
export default {
state,
actions,
mutations,
}
这是商店
/**
* Imports
*/
import Vue from 'vue'
import Vuex from 'vuex'
/**
* Vuex
*/
Vue.use(Vuex)
/**
* Global state
*/
import * as actions from './actions'
import * as getters from './getters'
import * as mutations from './mutations'
/**
* Modules
*/
import gate from './modules/gate'
import events from './modules/events'
import subEvents from './modules/subEvents'
import categories from './modules/categories'
import people from './modules/people'
import roles from './modules/roles'
import institutions from './modules/institutions'
import environment from './modules/environment'
/**
* State
*/
const state = {
mounted: false,
}
/**
* Store
*/
let store = new Vuex.Store({
state,
actions,
getters,
mutations,
modules: {
events,
people,
categories,
environment,
subEvents,
gate,
roles,
institutions,
},
})
store.dispatch('environment/absorbLaravel')
export default store
这是 merge_object 助手:
window.merge_objects = (target, ...sources) => {
return Object.assign(target, ...sources)
}
因此,如果您查看商店导入,您会看到子事件是在事件之后加载的,并且上面的子事件商店中的操作 select()(最初来自 mixin)正在加载超载,但是当我调用未超载的 events/select() 时,我在控制台中收到 'subevent select' 消息(dd() 是一个帮助程序)
这张图片稍微解释一下
问题是 Object.assign
没有创建副本,而是修改了作为第一个参数传递给它的对象。该函数将 return 第一个对象。
const a = {};
Object.assign(a, { a: 1 });
console.log(a); // { a: 1 }
在你的情况下,我认为你不需要对象的深度克隆。您只是不想直接修改 mixin。如果您使用新创建的对象作为第一个参数调用 Object.assign
,您将对下一个参数中的所有对象进行浅表复制。
Object.assign({}, target, ...sources)
const a = {};
Object.assign({}, a, { a: 1 });
console.log(a); // {}
如果您需要深度克隆(例如,因为您的对象中有您不想在实例之间共享的嵌套对象,我建议您使用 lodash.merge
.