Vue:如何在mapFields中使用组件prop

时间:2019-02-22 18:32:42

标签: javascript vue.js vuex

我有常规组件和vuex存储。为了简化双向绑定,我使用vuex-map-fields。在组件方面,它具有mapFields方法,该方法创建带有突变的get&set。 我想通过namespace从vuex模块传递props,但这似乎是不可能的。

<my-component namespace="ns1" />

// my-component code
export default {
  props: ["namespace"],
  computed: {
    ...mapFields(??this.namespace??, ["attr1", "attr2"])
  }
}

当然,无法以这种方式使用this,因此我们无法使用道具。在这种情况下如何将名称空间指定为prop?

1 个答案:

答案 0 :(得分:2)

问题(可能是您收集到的)是,在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()函数不支持我们想要做的事情,因此我们将其删除,并假定始终传入名称空间(并且存储模块使用标准的{{ 1}}和getField函数)。

我改编了vuex-map-fields Codesandbox示例here中的一个。
请注意,为方便起见,命名空间位于updateField中,而不是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>