vue.js - VueJs : Form handling with Vuex and inputs generated with an API

标签 vue.js vuejs2 vue-component vuex

这是一个组件示例:

<script>
    export default {
        name: 'my-form',

        computed: {
            myModules() {
                return this.$store.state.myModules;
            }
        }
</script>

<template>
    <form>
        <p v-for="module in myModules">
            <input type="checkbox" :value="module.id" />
            <label>module.name</label>
        </p>
        <button type="submit">Submit</button>
    </form>
</template>

关联商店:

    state: {
        myModules: []
    },

    mutations: {
        setModules(state, modules) {
            state.myModules = modules;
        }
    },

    actions: {
        getModules({commit}) {
            return axios.get('modules')
            .then((response) => {
                commit('setModules', response.data.modules);
            });
        }
    }

最后是 API“getModules”返回的示例:

modules : [
    {
        id: 1,
        name: 'Module 1',
        isActive: false
    },
    {
        id: 2,
        name: 'Module 2',
        isActive: false
    },
    {
        id: 3,
        name: 'Module 3',
        isActive: false
    }
]

我的问题:当我直接在商店中选中与关联模块对应的复选框时,将每个模块的“isActive”属性更改为“true”的最佳方法是什么?

我知道 Vuex 的文档建议使用“Two-way Computed Property ”来管理表单,但这里我不知道 API 可能返回的模块数量,也不知道它们的名称。

提前谢谢您!

最佳答案

这是一个有点邪恶的方法,但它确实有效。您可以为循环中访问的每个项目创建一个访问器对象:

const store = new Vuex.Store({
  mutations: {
    setActive (state, {index, value}) {
      state.modules[index].isActive = value
    }
  },
  state: {
    modules : [
      {
        id: 1,
        name: 'Module 1',
        isActive: false
      },
      {
        id: 2,
        name: 'Module 2',
        isActive: false
      },
      {
        id: 3,
        name: 'Module 3',
        isActive: false
      }
    ]
  }
});
const app = new Vue({
  el: '#target',
  store,
  methods: {
    model (id) {
      const store = this.$store;
      // here i return an object with value property that is bound to 
      // specific module and - thanks to Vue - retains reactivity
      return Object.defineProperty({}, 'value', {
        get () {
          return store.state.modules[id].isActive
        },
        set (value) {
          store.commit('setActive', {index: id, value});
        }
      });
    }
  }
})
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<script src="https://unpkg.com/vuex/dist/vuex.min.js"></script>
<div id="target">
  <div v-for="(item, id) in $store.state.modules">
    Module #{{ item.id }} state: {{ item.isActive }}
  </div>
  <div v-for="(item, id) in $store.state.modules">
    <label>
      Module #{{ item.id }}
      <input type="checkbox" v-model="model(id).value"/>
    </label>
  </div>
</div>

这仍然是一种相当困惑的方法,但至少您不必直接在模板中提交突变。在 Vue.set() 的帮助下,您甚至可以使用这种方法来克服标准 react 性警告。

关于vue.js - VueJs : Form handling with Vuex and inputs generated with an API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49028614/

相关文章:

javascript - VueJs 验证父组件中的子组件名称

vue.js - Vuetify - 在 v-list-tile-content 中居中内容

javascript - Vue 中的无限更新循环

javascript - 在 Vue 中使用 v-for 处理 v-if 的正确方法

vue.js - 如何通过 vue 组件中的 vuex 存储获取响应 ajax?

vue.js - 在导航选项卡上切换处于事件状态的 css 类

javascript - 如何在 vue js html 中根据时间显示 "Closed"或 "Open"?

javascript - Vue 2组件 Prop 得到错误的值

css - bootstrap vue(b-tabs)在 safari 浏览器中单击时显示蓝色轮廓

javascript - 为Vue-Multipane组件添加分页功能