【问题标题】:Should we use v-model to modify Vuex store?我们应该使用 v-model 来修改 Vuex 存储吗?
【发布时间】:2019-07-22 12:16:14
【问题描述】:

您好,我是 Vue 的初学者,我确实遇到了一个困扰我的问题。 我想知道我们应该使用 v-model 指令来修改 vuex 商店吗? Vuex 说我们应该只通过突变来修改 vuex 存储,但是 v-model 使一切变得更容易和更短。(我问是因为我找不到明确的答案)

【问题讨论】:

    标签: javascript vue.js vuejs2 vuex v-model


    【解决方案1】:

    https://vuex.vuejs.org/guide/forms.html

    在严格模式下使用 Vuex 时,在属于 Vuex 的状态上使用 v-model 可能有点棘手。

    处理它的“Vuex 方式”是绑定<input> 的值并在输入或更改事件上调用操作。

    请务必查看该页面上的简单“双向计算属性”示例:

    <input v-model="message">
    
    computed: {
      message: {
        get () {
          return this.$store.state.obj.message
        },
        set (value) {
          this.$store.commit('updateMessage', value)
        }
      }
    }
    

    【讨论】:

    • 这是否适用于消息中更复杂的数据?
    • 感谢您的解决方案。我将其修改为使用 dispatch("SomeAction") 而不是提交。因为使用动作是推荐的方式。
    【解决方案2】:

    我认为这里的任何答案中都没有提到的另一个好选择是使用vuex-map-fields。事实上,图书馆作者有written a very nice explanation 为图书馆的用处。根据其 GitHub 页面,要使用该库,您可以执行以下操作:

    在你的 Vuex Store 中,你可以有一个类似这样的 sn-p:

    import Vue from 'vue';
    import Vuex from 'vuex';
    
    import { getField, updateField } from 'vuex-map-fields';
    
    Vue.use(Vuex);
    
    export default new Vuex.Store({
      // ...
      modules: {
        fooModule: {
          namespaced: true,
          state: {
            foo: '',
          },
          getters: {
            getField,
          },
          mutations: {
            updateField,
          },
        },
      },
    });
    

    在你的组件代码中,你可以有类似这样的东西:

    <template>
      <div id="app">
        <input v-model="foo">
      </div>
    </template>
    
    <script>
    import { mapFields } from 'vuex-map-fields';
    
    export default {
      computed: {
        // `fooModule` is the name of the Vuex module.
        ...mapFields('fooModule', ['foo']),
      },
    };
    </script>
    

    我在这个答案的第一句话中链接到的库的 GitHub 存储库中显示了各种用例的其他示例。

    【讨论】:

      【解决方案3】:

      上述解决方案也可以通过突变实现:

      <template>
        <input v-model="message">
      </template>
      
      <script>
      import { mapMutations, mapState } from 'vuex';
      
      export default {
        computed: {
          ...mapState({messageFromStore: 'message'}),
          message: {
            get() {
              return this.messageFromStore;
            },
            set(value) {
              this.updateMessage(value);
            }
          }
        },
        methods: {
          ...mapMutations('updateMessage')
        }
      };
      </script>
      

      【讨论】:

      • 我猜你的意思是&lt;input v-model="tab"&gt; 在第 2 行
      【解决方案4】:

      对此我的解决方案是使用 getter 设置 value@input 来调用突变。

      <input
        type="text"
        :value="$store.getters.apartmentStreet"
        @input="value => $store.commit('apartmentValue', { handle: 'street', value })"
      >
      

      getters.js:

      export default {
        apartmentStreet: state => state.apartment.street,
      };
      

      mutations.js

      export default {
        apartmentValue(state, payload) {
          let oldValue = state.apartment[payload.handle];
          let newValue = payload.value;
          if (newValue !== oldValue) state.apartment[payload.handle] = payload.value;
        }
      };
      

      如果您使用此方法,请务必检查您想要的事件。

      【讨论】:

        【解决方案5】:

        我使用这个解决方案。

        data() {
          return {
            formData: {
              username: '',
              email: '',
              bio: {
                firstName: '',
                lastName: ''
              },
              games: ['civ4', 'caesar3', 'homeworld', 'cataclysm'],
                 
            }
          }
        },
        computed: {
          ...mapGetters({   //or mapState
            user: 'users'
          })
        },
        watch: {
          user(newValue) {
            this.formData.username = newValue.name;
            this.formData.email = newValue.email;
            this.formData.bio.firstName = newValue.bio.firstName;
            this.formData.bio.lastName = newValue.bio.lastName;
            this.formData.games = newValue.games.map(x=> { return x });
          }
        },
        beforeCreate: fucntion() {
          this.$store.dispatch('getUser');
        }

        然后你就经常使用 v-model。 从存储中制作对象的深层副本很重要,例如使用数组的映射,以及我如何在里面处理对象。

        而且,您还需要在商店中启动此用户对象,并使用空字段。

        【讨论】:

          【解决方案6】:

          可以,但不是最佳做法。

          正如文档所说,状态应该只在突变内部更新以保持对状态的控制。

          但如果你真的想这样做,你可以这样做:

          v-model="$store.state.yourProperty"
          

          【讨论】:

          • 是的,但是为什么我们不应该使用 v-model (因为我们应该只通过突变来修改 vuex 存储)但是 v-model 正在做什么不建议通过 v- 来修改 vuex 存储模型指令?
          • @TristanDeoliveira 如果有人不关心“高级调试助手”,因为他正在构建一个简单的应用程序怎么办? v-modeling store 会直接导致其他问题吗?当我开始学习 Vue 时,我确实使用 v-models 直接链接存储(我使用了 getter,但不是状态对象),我不记得有任何问题。对于小型应用程序来说,最佳实践不是矫枉过正吗?
          • @Eggon 同意,vuex 应该在幕后处理这个问题......
          猜你喜欢
          • 2019-05-19
          • 1970-01-01
          • 2021-04-17
          • 1970-01-01
          • 1970-01-01
          • 2019-11-09
          • 1970-01-01
          • 1970-01-01
          • 2020-02-09
          相关资源
          最近更新 更多