问题(正如您可能收集到的)是计算属性是在 this 可用之前构建的,但是您可以通过将 this.namespace 属性的解析推迟到计算属性被调用来解决它(这不会直到组件构建完成)。
这个概念是基于这篇帖子Generating computed properties on the fly。
基本模式是使用 get() 和 set() 进行计算
computed: {
foo: {
get() { this.namespace...},
set() { this.namespace...},
}
}
但我们可以基于 vuex-map-fields mapFields() 函数创建一个辅助函数,而不是在组件中全部输入(参见 here 原文)。
vuex-map-fields 自带的normalizeNamespace() 函数不支持我们想做的,所以我们把它去掉,假设总是传入命名空间(并且 store 模块使用标准的getField 和updateField 函数)。
我已经改编了 vuex-map-fields Codesandbox 示例之一here。
请注意,为了方便起见,命名空间位于 data 而不是 props,但 props 也应该可以工作。
模板
<template>
<div id="app">
<div>
<label>foo </label> <input v-model="foo" /> <span> {{ foo }}</span>
</div>
<br />
<div>
<label>bar </label> <input v-model="bar" /> <span> {{ bar }}</span>
</div>
</div>
</template>
助手
<script>
const mapFields2 = (namespaceProp, fields) => {
return Object.keys(fields).reduce((prev, key) => {
const path = fields[key];
const field = {
get() {
const namespace = this[namespaceProp];
const getterPath = `${namespace}/getField`;
return this.$store.getters[getterPath](path);
},
set(value) {
const namespace = this[namespaceProp];
const mutationPath = `${namespace}/updateField`;
this.$store.commit(mutationPath, { path, value });
}
};
prev[key] = field;
return prev;
}, {});
};
export default {
name: "App",
data() {
return {
nsProp: "fooModule"
};
},
computed: {
...mapFields2("nsProp", { foo: "foo", bar: "bar" })
}
};
</script>
商店
import Vue from "vue";
import Vuex from "vuex";
import { getField, updateField } from "vuex-map-fields";
import App from "./App";
Vue.use(Vuex);
Vue.config.productionTip = false;
const store = new Vuex.Store({
modules: {
fooModule: {
namespaced: true,
state: {
foo: "initial foo value",
bar: "initail bar value"
},
getters: {
getField
},
mutations: {
updateField
}
}
}
});
new Vue({
el: "#app",
components: { App },
store,
template: "<App/>"
});