如何有效地为Vuex状态属性的所有子属性创建getter和setter?

时间:2020-06-01 13:33:03

标签: vue.js vuejs2 vuex

我在任何地方都找不到答案。

假设我们有Vuex存储,其中包含以下数据:

Vuex商店

state: {
  dialogs: {
    dialogName1: {
      value: false,
      data: {
        fileName: '',
        isValid: false,
        error: '',
        ... 10 more properties 
      }
    },
    dialogName2: {
      value: false,
      data: {
        type: '',
        isValid: false,
        error: '',
        ... 10 more properties
      }
    }
  }
}

Dialogs.vue

<div v-if="dialogName1Value">
  <input 
    v-model="dialogName1DataFileName"
    :error="dialogName1DataIsValid"
    :error-text="dialogName1DataError"
  >

  <v-btn @click="dialogName1Value = false">
    close dialog
  </v-btn>
</div>
<!-- the other dialogs here -->

问题

假设我们需要在Dialogs.vue中修改其中一些属性。

有效地为每个对话框属性创建一个getter和setter的最佳实践是什么,而不必像这样手动进行所有操作:

computed: {
  dialogName1Value: {
    get () {
      return this.$store.state.dialogs.dialogName1.value
    },
    set (value) {
      this.$store.commit('SET', { key: 'dialogs.dialogName1.value', value: value })
    }
  },
  dialogName1DataFileName: {
    get () {
      return this.$store.state.dialogs.dialogName1.data.fileName
    },
    set (value) {
      this.$store.commit('SET', { key: 'dialogs.dialogName1.data.fileName', value: value })
    }
  },
  dialogName1DataIsValid: {
    get () {
      return this.$store.state.dialogs.dialogName1.data.isValid
    },
    set (value) {
      this.$store.commit('SET', { key: 'dialogs.dialogName1.data.isValid', value: value })
    }
  },
  dialogName1DataIsError: {
    get () {
      return this.$store.state.dialogs.dialogName1.data.error
    },
    set (value) {
      this.$store.commit('SET', { key: 'dialogs.dialogName1.data.error', value: value })
    }
  },
  ... 10 more properties 

这只是4个属性...

我想我可以在created()中以编程方式生成那些计算出的属性,但这真的是正确的方法吗?

是否存在我不知道的针对此问题的显而易见的,众所周知的解决方案?

2 个答案:

答案 0 :(得分:1)

可以使

getters接受参数作为参数-这可以是您要返回的基础状态的“一部分”。这称为Method-style access。例如:

getFilename: (state) => (dialogName) => {
    return state.dialogs[dialogName].data.fileName
}

然后您可以将此吸气剂称为:

store.getters.getFilename('dialogName1')

请注意,方法样式访问不提供您通过属性样式访问获得的“计算属性”样式缓存。

答案 1 :(得分:1)

要仅在一个中央功能中设置这些内容,您可以使用以下内容:

<input 
  :value="dialogName1DataFileName"
  @input="update_inputs($event, 'fileName')">

// ...
methods:{
  update_inputs($event, whichProperty){
    this.$store.commit("SET_PROPERTIES", {newVal: $event.target.value, which:"whichProperty"})
  }
}

变异处理程序:

// ..

mutations:{
  SET_PROPERTIES(state, payload){
    state.dialogName1.data[payload.which] = payload.newVal
  }
}

让我解释一下我们上面所做的事情。首先,我们将v-model类型更改为:value@input基。基本上,您可以认为,该属性的:valuegetter,而@inputsetter。然后我们没有首先提交,而是调用update_inputs函数来提交,因为我们应该确定要提交的内部属性,因此我们确实将此数据作为方法参数发送(例如,上面的代码是“ fileName”),然后,我们使用属性将更改的data和info的新值提交此更改。您可以将此逻辑纳入整个代码块,这将解决您的问题。

还有一个,如果您想了解更多有关本文的信息,将为您提供更多帮助: https://pekcan.dev/v-model-using-vuex/