【问题标题】:How to update Vuex store from v-model input in case of v-for在 v-for 的情况下如何从 v-model 输入更新 Vuex 存储
【发布时间】:2018-07-09 04:58:53
【问题描述】:

我说过一个数组中有 10 个对象,例如 policies = [{name:'a',text:''},{name:'b',text:''},....]

它们使用 v-for 进行迭代以显示标签 A:输入框,其文本属性绑定为 v-model。 每当策略的文本在 v-model 中发生更改时,我想触发突变。

这是它的小提琴链接。 https://jsfiddle.net/dmf2crzL/41/

【问题讨论】:

  • 您的意思是您想知道输入中的文本何时发生变化?你的问题和演示代码与vuex无关。
  • 我想提交一个突变,所以当 v-model 中的值发生变化时我想要一个动作
  • 为什么不在输入上使用@keyup 并在函数内触发你的提交/

标签: vue.js vuex


【解决方案1】:

我们假设您想同时使用 v-model 的 2-way binding 和 Vuex store。

您的问题是您希望 Vuex 以严格模式存储

const store = new Vuex.Store({
  // ...
  strict: true
})

所以你所有的变异都应该通过 Vuex 商店,你可以在 Vue.js 开发工具中看到它。

方法一:我们可以通过使用克隆对象来避免Vuex错误,并使用watcher来提交突变。

const store = new Vuex.Store({
  strict: true,
  state: {
    formdata: [{
      label: 'A',
      text: 'some text'
    },{
    label: 'B',
    text: 'some other text'
    },{
    label: 'C',
    text: ' this is a text'
    }]
  },
  mutations: {
    updateForm: function (state, form) {
    var index = state.formdata.findIndex(d=> d.label === form.label);
      Object.assign(state.formdata[index], form);
    }
  }
});

new Vue({
  el: '#app',
  store: store,
  data () {
    return {
      //deep clone object
      formdata: JSON.parse(JSON.stringify(this.$store.state.formdata))
    };
  },
  computed: {
    formdata() {
      return this.$store.state.formdata
    }
  },
  watch: {
    formdata: function(form)
        this.$store.commit('updateForm', form);
    }
  }
})

方法 2:您可以使用计算的 get/set 根据vuex doc 提交您的突变

computed: {
  message: {
    get () {
      return this.$store.state.obj.message
    },
    set (value) {
      this.$store.commit('updateMessage', value)
    }
  }
}

【讨论】:

  • 如何使用索引(即在 v-for 循环中)进行计算的 setter/getter?
  • 我不确定方法 1 是否有效。它会触发警告,因为您有一个同名的 formdata 作为计算属性,并且作为数据属性创建了它所指的“this.formdata”的问题。
【解决方案2】:

我发现另一种有用的方法:

  1. 将 v-model 替换为 (v-on) 函数
  2. 该函数触发突变
  3. 突变(商店中的“函数”)改变了状态中的值
  4. getter(在存储中“计算”)“侦听”属性值的变化并相应地变化。

这是一个如何使用 Vuex 过滤卡片的示例(而不是 v-model:

触发函数“updateFilter”的输入:

    <input type="text" placeholder="filter" v-on:input='updateFilter'>

触发突变(提交)的函数(方法):

  methods: {
updateFilter(event){
  this.$store.commit('updateFilter', event.target.value);
}

在 store.js 中,一个改变数据(状态)的突变:

mutations: {
    updateFilter (state, filter) {
        state.filter = filter; 
    },

国家:

state: {filter: ""}

以及“监听”状态变化的 getter(计算)。

getters: {
    filteredGames: state => {
        //your filter code here
          return filtered;
        })
    }, 

最后,需要过滤的组件有这个计算(getter):

  computed: {
filtered() {
  return this.$store.getters.filteredGames;
}

【讨论】:

    【解决方案3】:

    矿库 vuex-dot 简化了 vuex 商店的反应性(当然还有 v-model)的使用

    https://github.com/yarsky-tgz/vuex-dot

    <template>
      <form>
        <input v-model="name"/>
        <input v-model="email"/>
      </form>
    </template>
    
    <script>
      import { takeState } from 'vuex-dot';
    
      export default {
        computed: {
          ...takeState('user')
            .expose(['name', 'email'])
            .dispatch('editUser')
            .map()
        }
      }
    </script>
    

    【讨论】:

    • @yaroslave 你的库是否允许访问存储中嵌套对象的状态..?
    • @Wikki 是的,您可以使用点,例如。 'users.0.email'
    猜你喜欢
    • 2018-10-02
    • 2019-04-30
    • 2020-08-11
    • 1970-01-01
    • 2021-10-23
    • 1970-01-01
    • 2021-06-27
    • 2021-07-27
    相关资源
    最近更新 更多