我们应该使用 v-model 来修改 Vuex 存储吗?

Posted

技术标签:

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

您好,我是 Vue 的初学者,我确实遇到了一个困扰我的问题。 我想知道我们应该使用 v-model 指令来修改 vuex 商店吗? Vuex 说我们应该只通过突变来修改 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 存储模型指令? > : vuejs.org/v2/guide/state-management.html @TristanDeoliveira 如果有人不关心“高级调试助手”,因为他正在构建一个简单的应用程序怎么办? v-modeling store 会直接导致其他问题吗?当我开始学习 Vue 时,我确实使用 v-models 直接链接存储(我使用了 getter,但不是状态对象),我不记得有任何问题。对于小型应用程序来说,最佳实践不是矫枉过正吗? @Eggon 同意,vuex 应该在幕后处理这个问题......

以上是关于我们应该使用 v-model 来修改 Vuex 存储吗?的主要内容,如果未能解决你的问题,请参考以下文章

VueJS v3、Vuex 和 Composition API 以及输入字段上的 v-model

如何优雅地使用 v-model 和 Vuex store?

切换 Vuetify 导航抽屉 v-modeled 到 Vuex 变量

如何在 Vuetify 组件中使用 Vue v-model 绑定以及计算属性和 Vuex?

如何用 vuex 解决 v-model?

从 vuex 状态数组生成计算属性数组以用于 v-model