Vuex Mutation 最佳实践 - 将状态与有效负载合并

Vuex Mutation Best Practices - Merging State with Payload

我正在尝试使用 Vuex 避免以下代码。

//Product.js
const mutations = {
    SET_PRODUCT_DATA(state, product) {
        state.title = product.title
        state.variantId = product.variantId
        state.handle = product.handle
        state.tags = product.tags
        state.productType = product.productType
        state.featureImage = product.featureImage
        state.vendor = product.vendor
        state.description = product.description
        state.images = product.images
        state.presentmentPrices = product.presentmentPrices
        state.available = product.available
        state.quantity = product.quantity
        state.length = product.length
        state.width = product.width
        state.height = product.height
        state.weight = product.weight
        state.features = product.features
        state.sizeMeta = product.sizeMeta
        state.swatch = product.swatch
    },
}

但是,如果我尝试将状态对象与我的有效负载合并,它就不起作用(我相信这与 vue 如何处理反应性有关,但我还没有完全理解)。

const mutations = {
    SET_PRODUCT_DATA(state, product) {
        state = { ...state, ...product} //doesn't work
    },
}

我还想避免在我的状态下定义一个对象,例如 'data' 我将在其中分配此有效负载。这种接缝就像不必要的嵌套。

const mutations = {
    SET_PRODUCT_DATA(state, product) {
        state.data = product //avoid 
    },
}

您可以使用 Object.keys 并遍历它们以复制所有值

const mutations = {
    SET_PRODUCT_DATA(state, product) {
        Object.keys(product)
              .forEach(key => {
                state[key] = product[key]
    },
}

如果产品对象键始终与修改后的状态属性相同,您可以选择使用 set() 方法设置每个 属性,这会在保留反应性的同时修改状态根 属性:

import Vue from 'vue'

SET_PRODUCT_DATA(state, product) {
    Object.keys(product).forEach(key => {
      Vue.set(state, key, product[key])
    }
},

此外,使用扩展运算符将状态与产品对象合并是行不通的,因为它将整个状态克隆到一个新对象中,这显然会失去现有状态的反应性。

如果你只传递一个已经存在状态道具的对象,那么你可以使用 Object.assign:

const mutations = {
    SET_PRODUCT_DATA(state, product) {
        Object.assign(state, product)
    },
}