Ins*_*ane 8 vue.js jestjs vuex vuejs2 vue-test-utils
我正在使用辅助函数在我的笑话中创建一个商店。helper 函数使用 deepmerge 将基本配置与自定义配置合并。这会导致多个控制台警告
[vuex] state field "cart" was overridden by a module with the same name at "cart"
[vuex] state field "customer" was overridden by a module with the same name at "customer"
[vuex] state field "checkout" was overridden by a module with the same name at "checkout"
Run Code Online (Sandbox Code Playgroud)
store.js(为了演示目的减少到最低限度)
import cart from './modules/cart'
import checkout from './modules/checkout'
import customer from './modules/customer'
Vue.use(Vuex)
export const config = {
modules: {
cart,
customer,
checkout,
},
}
export default new Vuex.Store(config)
Run Code Online (Sandbox Code Playgroud)
测试utils.js
import merge from 'deepmerge'
import { config as storeConfig } from './vuex/store'
// merge basic config with custom config
export const createStore = config => {
const combinedConfig = (config)
? merge(storeConfig, config)
: storeConfig
return new Vuex.Store(combinedConfig)
}
Run Code Online (Sandbox Code Playgroud)
利用里面的辅助函数
somejest.test.js
import { createStore } from 'test-utils'
const wrapper = mount(ShippingComponent, {
store: createStore({
modules: {
checkout: {
state: {
availableShippingMethods: {
flatrate: {
carrier_title: 'Flat Rate',
},
},
},
},
},
}),
localVue,
})
Run Code Online (Sandbox Code Playgroud)
如何解决控制台警告?
我认为这个警告在这种情况下有些误导。这在技术上是正确的,只是没有帮助。
以下代码将生成相同的警告。它不使用deepmerge,vue-test-utils或者jest但我相信根本原因与原来的问题相同:
const config = {
state: {},
modules: {
customer: {}
}
}
const store1 = new Vuex.Store(config)
const store2 = new Vuex.Store(config)Run Code Online (Sandbox Code Playgroud)
<script src="https://unpkg.com/vue@2.6.11/dist/vue.js"></script>
<script src="https://unpkg.com/vuex@3.4.0/dist/vuex.js"></script>Run Code Online (Sandbox Code Playgroud)
此示例中有两个关键部分需要触发警告:
state配置中的根对象。问题中的代码肯定有多个商店。一个是在 的末尾创建的store.js,另一个是由 创建的createStore。
该问题没有显示根state对象,但确实提到代码已减少。我假设完整的代码确实有这个对象。
那么为什么这会触发该警告呢?
模块state存储在根state对象内。尽管我的示例中的模块没有明确包含任何模块,但state它仍然存在。这state将存储在state.customer. 因此,当创建第一个商店时,它会customer向该根state对象添加一个属性。
到目前为止还没有问题。
但是,当创建第二个商店时,它使用相同的根state对象。在此阶段制作副本或合并配置不会有帮助,因为复制的配置state也将具有该customer属性。第二个商店也尝试添加到customerroot state。然而,它发现该属性已经存在,感到困惑并记录警告。
官方文档对此有一些介绍:
https://vuex.vuejs.org/guide/modules.html#module-reuse
解决此问题的最简单方法是使用根函数state:
state: () => ({ /* all the state you currently have */ }),
Run Code Online (Sandbox Code Playgroud)
每个商店都会调用该函数并获取自己的状态副本。data这与使用组件的函数相同。
如果您实际上不需要root,state您也可以通过完全删除它来修复它。如果没有state指定,那么 Vuex 将state每次创建一个新的根对象。