【问题标题】:Vuex input with v-model not reactive带有 v-model 的 Vuex 输入不是反应式的
【发布时间】:2017-03-13 01:25:01
【问题描述】:

我尝试尽可能简单地解释它。我有这样的东西。简单的 Vue 根目录、Vuex 存储和在导航栏 id 中使用 v-model 输入。

那个输入不是反应式的……为什么?!

HTML

<div id="navbar">
    <h2>@{{ test }}</h2>
    <input v-model="test" />
</div>

store.js

import Vuex from 'vuex'

export const store = new Vuex.Store({
  state: {
    test: 'test'
  },
  getters: {
    test (state) {
      return state.test
    }
  }
})

Vue 根目录

import { store } from './app-store.js'

new Vue({
  el: '#navbar',
  store,
  computed: {
    test () {
      return this.$store.getters.test
    }
  }
})

【问题讨论】:

    标签: javascript vue.js vuex


    【解决方案1】:

    您正在绑定到一个计算属性。为了设置计算属性的值,您需要编写 getset 方法。

    computed:{
        test:{
            get(){ return this.$store.getters.test; },
            set( value ){ this.$store.commit("TEST_COMMIT", value );}
        }
    }
    

    在你的商店里

    mutations:{
        TEST_COMMIT( state, payload ){
            state.test=payload;
        }
    }
    

    现在,当您更改绑定到 test 的输入值时,它将触发对存储的提交,从而更新其状态。

    【讨论】:

      【解决方案2】:

      通过使用我的库,您可以轻松地将 v-model 与 Vuex 一起使用(每次更改都会触发动作/突变):

      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'])
              .commit('editUser') // payload example: { name: 'Peter'}
              .map()
          }
        }
      </script>
      

      【讨论】:

      • 自我推销的答案没有帮助。
      【解决方案3】:

      您不想为此使用v-model。相反,请在输入字段和 methods 挂钩中使用 @input="test"

       test(e){
          this.$store.dispatch('setTest', e.target.value)
       }
      

      在您的Vuex 商店内:

      mutations

         setTest(state, payload){
            state.test = payload
         },
      

      actions:

      setTest: (context,val) => {context.commit('setTest', val)},
      

      输入现在应该是响应式的,您应该会在@{{test}} 中看到结果

      这是我如何使用 Vuex 处理用户输入的示例:http://codepen.io/anon/pen/gmROQq

      【讨论】:

        【解决方案4】:

        computed 属性是单向的。如果您想要双向绑定,请按照其他答案的建议创建一个 setter,或者改用 data 属性。

        import { store } from './app-store.js'
        
        new Vue({
          el: '#navbar',
          store,
          // computed: {
          //   test() {
          //     return this.$store.getters.test;
          //   }
          // }
          data: function() {
            return { test: this.$store.getters.test };
          }
        });
        

        但是 setter 更好地验证输入值。

        【讨论】:

          猜你喜欢
          • 2019-08-06
          • 2021-06-12
          • 2020-12-03
          • 2017-07-29
          • 2018-07-09
          • 2020-05-26
          • 2020-09-15
          • 2021-12-21
          • 2019-11-19
          相关资源
          最近更新 更多