如何在Vuex中正确混合和隔离对象

时间:2018-10-20 14:36:52

标签: vue.js vuex mixins

我正在尝试使用模块为Vuex创建某种mixin,但是操作在模块内混合在一起:

这是subEvents模块:

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()是它的助手)

这是一张说明它的图像

enter image description here

1 个答案:

答案 0 :(得分:1)

问题在于Object.assign不会创建副本,而是会修改您将其作为第一个参数传递的对象。该函数将返回第一个对象。

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的东西。