【问题标题】:How to elegantly use v-model and Vuex store?如何优雅地使用 v-model 和 Vuex store?
【发布时间】:2019-06-23 16:22:19
【问题描述】:

我正在寻找一种干净的方式来使用 v-model 和 vuex 存储。

Vuex 提供了几个辅助方法,非常有用,但在与 v-model 一起使用时有点烦人。

我今天使用 v-model 和我的模块化商店的方式就像

computed: {
  type: {
    get() {
      return this.$store.state.mymodule.type;
    },
    set(newValue) {
      this.$store.dispatch('mymodule/setType', newValue)
    }
}

这可行,但我发现最好利用 vuex 助手来避免样板代码(this.$store,模块名称,...)

好的,所以我首先想摆脱模块名称。 Vuex 提供了一个很棒的 createNamespacedHelpers,它返回模块化的帮助器。

让我们使用它:

import { createNamespacedHelpers } from 'vuex'

const { mapState, mapActions } = createNamespacedHelpers('some/nested/module')

所以,好的,我们现在有一个干净的 mapState 和 mapActions 函数,它们是模块专用的。

computed: {
  ...mapState(['type']) // No need here to specify module name :)
}

很酷,但由于 mapState 只有 get 功能,我无法设置调度功能来更新数据...

在使用 v-model 的情况下,我发现助手无法使用。我不能使用 mapState,因此我不能使用 createNamespacedHelpers。

那么:如何利用 Vuex 辅助函数和 v-model 的优势协同工作?

【问题讨论】:

  • 为什么你没有在你的组件中使用:value="computedValue" & @input="setterFunction"
  • 似乎您可以创建一个辅助函数来生成可设置的计算结果并像使用 ...mapState 一样使用它。

标签: javascript vue.js vuex vuex-modules


【解决方案1】:

你不能。没有优雅的方法可以将助手与 v-model 结合起来。但是 v-model 只是一个语法糖,所以也许最易读的方法是使用 helpers

computed: {
  ...mapGetters('path/to/module', ['type'])
},
methods: {
  ...mapActions('path/to/module', ['setType'])
}

没有 v-model

<input :value="type" @input="setType">

【讨论】:

    【解决方案2】:

    我最终发现最易读的方式如下:

    import { createNamespacedHelpers } from 'vuex'
    
    const { mapState, mapActions } = createNamespacedHelpers('some/nested/module')
    

    这样使用:

    computed: {
      ...mapGetters(['type'])
    },
    methods: {
      ...mapActions(['setType'])
    }
    

    并且没有 v-model

    <input :value="type" @input="setType($event.target.value)">
    

    【讨论】:

      【解决方案3】:

      试试这个。

      // in some utils/vuex.js file 
      export const mapSetter = (state, setters = {}) => (
        Object.keys(state).reduce((acc, stateName) => {
          acc[stateName] = {
            get: state[stateName],
         };
         // check if setter exists
         if (setters[stateName]) {
            acc[stateName].set = setters[stateName];
         }
      
         return acc;
       }, {})
      );
      

      在你的 component.vue 文件中

        import { mapSetter  } from 'path/to/utils/vuex.js';
        ...
      
        export default {
          name: 'ComponentName',
          computed: {
            ...mapSetter(
              mapState({
                result: ({ ITEMS }) => ITEMS.result,
                total: ({ ITEMS }) => ITEMS.total,
                current: ({ ITEMS }) => ITEMS.page,
                limit: ({ ITEMS }) => ITEMS.limit,
              }),
              {
                limit(payload) {
                  this.$store.dispatch({ type: TYPES.SET_LIMIT, payload });
                },
              },
            )
          },
        }
      

      现在 v-model 绑定应该可以工作了。

      【讨论】:

        猜你喜欢
        • 2020-02-09
        • 1970-01-01
        • 2019-11-09
        • 2018-10-02
        • 2021-08-21
        • 2019-05-19
        • 1970-01-01
        • 2018-12-14
        • 2019-08-06
        相关资源
        最近更新 更多