40

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

4

6 回答 6

75

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

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

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

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

<input v-model="message">

computed: {
  message: {
    get () {
      return this.$store.state.obj.message
    },
    set (value) {
      this.$store.commit('updateMessage', value)
    }
  }
}
于 2019-02-28T14:43:58.870 回答
8

我认为这里的任何答案中都没有提到的另一个好选择是使用vuex-map-fields。事实上,图书馆作者已经为图书馆的实用性写了一个非常好的解释。根据其 GitHub 页面,要使用该库,您可以执行以下操作:

在你的 Vuex Store 中,你可以有一个类似这样的代码片段:

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 存储库中显示了各种用例的其他示例。

于 2020-07-04T07:20:56.443 回答
6

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

<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>
于 2019-08-28T13:04:30.590 回答
2

我对此的解决方案是使用吸气剂来设置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,
};

突变.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;
  }
};

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

于 2020-06-23T06:23:23.007 回答
0

我使用这个解决方案。

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。从存储中制作对象的深层副本很重要,例如使用数组映射,以及我如何在里面处理对象。

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

于 2021-03-16T22:44:48.593 回答
-2

是的,您可以,但不是最佳做法。

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

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

v-model="$store.state.yourProperty"
于 2019-02-28T14:42:11.550 回答