【问题标题】:Vuex dynamic checkboxes bindingVuex 动态复选框绑定
【发布时间】:2018-07-26 03:21:18
【问题描述】:

我在使用 Vuex 绑定复选框时遇到问题。在复选框上,我使用带有 getter 和 setter 的变量的 v-model 来设置或获取存储中的值,问题是我在存储中得到错误的数据,我不明白是什么导致了问题。复选框绑定到存储属性,并且该属性必须包含来自复选框的 id 数组,但是当我多次单击复选框时,它会重写或删除存储值。谁能帮我理解为什么会发生这种情况? Link 到 jsFiddle。

代码

const store = new Vuex.Store({
state: {
checkboxes: {},
checked: {}
},
mutations: {
  setCheckboxes(state, dataObj){
    console.log(dataObj);
    state.checkboxes = dataObj.data;
    let firstElem = dataObj.data[Object.keys(dataObj.data)[0]];
    state.checked[firstElem.parent_id] = [firstElem.id];
    console.log(state.checked);
  },
  setTreeState(state, dataObj){
    state.checked[dataObj.id] = dataObj.value;
    console.log(state.checked);
  }
 }
});


Vue.component('checkboxTree', {
  template: "#checkboxTree",
});

Vue.component('checkboxToggle', {
  template: "#checkboxToggle",
  data(){
    return {
      store
    }
  },
  computed: {
    value:{
      get(){ 
        return store.state.checked[this.checkbox.parent_id];
      },
      set(val){ 
        store.commit({
        type: 'setTreeState',
        id: this.checkbox.parent_id,
        value: val
      });
    },
  },
},
props: ['checkbox']
});

const app = new Vue({
  el: "#app",
  store,
  data: {
    checkboxData: {
    ...
    },

  },
  mounted(){
    this.$store.commit({
      type: 'setCheckboxes',
      data: this.checkboxData
    });
  }
})

模板

<div id="app">
  <checkbox-tree :checkboxData="checkboxData"></checkbox-tree>
</div>    

<template id="checkboxTree">
  <div>
    <p>checkbox tree</p>
  <form>
   <ul>
     <li v-for="checkbox in $store.state.checkboxes">
       <checkbox-toggle :checkbox="checkbox"></checkbox-toggle>
     </li>
   </ul>
  </form>
  </div>
</template>

<template id="checkboxToggle">
  <div>
  <label>{{ checkbox.id }}</label>
   <input type="checkbox" 
    :value="checkbox.id"
    :id="'checkbox-' + checkbox.id"
    :name="'checkbox-' + checkbox.id"
    v-model="value"
    >
  </div>
</template>

【问题讨论】:

  • 请描述您希望如何组织该州。目前还不清楚checked: {} 对象究竟应该是什么样子。它应该包含ID吗?那么为什么它不是一个对象而不是一个数组呢?当您指定这些内容时,会更容易为您提供帮助。

标签: javascript checkbox vue.js vuex


【解决方案1】:

好的,假设您希望 checked 包含选定对象的 id,我必须对您的代码进行重大调整:

const removeFromArray = (array, value) => {
	const newArray = [...array];
  const index = newArray.indexOf(value);
  if (index > -1) {
    newArray.splice(index, 1);
    return newArray;
  }
  return array;
}

const store = new Vuex.Store({
  state: {
    checkboxes: {},
    checked: [],
  },
  mutations: {
  	addToChecked(state, id) {
    	state.checked.push(id);
    },
		removeFromChecked(state, id) {
      const newArray = removeFromArray(state.checked, id);
      state.checked = newArray;
    },
    setCheckboxes(state, data) {
      state.checkboxes = data;
    },
  }
});

Vue.component('checkboxTree', {
  template: "#checkboxTree",
  computed: {
    checkboxes() {
    	return this.$store.state.checkboxes;
    },
  },
});

Vue.component('checkboxToggle', {
  template: "#checkboxToggle",
	computed: {
    value:{
      get(){
        return this.$store.state.checked.indexOf(this.checkbox.id) > -1;
      },
      set(val){
        const mutation = val ? 'addToChecked' : 'removeFromChecked';
        this.$store.commit(mutation, this.checkbox.id);
      },
    },
  },
  props: ['checkbox'],
});

const app = new Vue({
  el: "#app",
  store,
  data: {
    checkboxData: {
      "5479": {
        "id": 5479,
        "title": "Место оказания услуг",
        "type": "checkbox",
        "dependencies": "",
        "description": "",
        "parent_id": 5478,
        "npas": ""
      },
      "5480": {
        "id": 5480,
        "title": "Способы оказания услуг",
        "type": "checkbox",
        "dependencies": "",
        "description": "",
        "parent_id": 5478,
        "npas": "50"
      },
      "5481": {
        "id": 5481,
        "title": "Объем и порядок содействия Заказчика в оказании услуг",
        "type": "checkbox",
        "dependencies": "",
        "description": "",
        "parent_id": 5478,
        "npas": "54"
      },
    }
  },
  computed: {
  	stateRaw() {
    	return JSON.stringify(this.$store.state, null, 2);
    },
  },
  mounted() {
    this.$store.commit('setCheckboxes', this.checkboxData);
    const firstElementKey = Object.keys(this.checkboxData)[0];
    const firstElement = this.checkboxData[firstElementKey];
    this.$store.commit('addToChecked', firstElement.id);
  }
})
<script src="https://unpkg.com/vue"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/3.0.1/vuex.js"></script>

<div id="app">
  <checkbox-tree :checkboxData="checkboxData"></checkbox-tree>
  <pre v-text="stateRaw"></pre>
</div>

<template id="checkboxTree">
  <div>
    <p>checkbox tree</p>
    <form>
      <ul>
        <li v-for="checkbox in checkboxes">
          <checkbox-toggle :checkbox="checkbox"></checkbox-toggle>
        </li>
      </ul>
    </form>
  </div>
</template>

<template id="checkboxToggle">
  <div>
   <label>{{ checkbox.id }}</label>
   <input 
     type="checkbox" 
     :value="checkbox.id" 
     :id="'checkbox-' + checkbox.id" 
     :name="'checkbox-' + checkbox.id"
     v-model="value">
    {{value}}
  </div>
</template>

使用此代码作为示例,您可以随意填充checked

另外,给你一个 jsfiddle 链接:https://jsfiddle.net/oniondomes/ckj7mgny/

【讨论】:

  • 谢谢,您的代码确实解决了我的问题,但您能给我一点反馈吗?我是否将 Vuex 错误地用于绑定复选框还是 Vuex 功能/错误?
  • 首先,我不太确定您使用的提交突变的语法是什么。通常你打电话给commit(type: &lt;String&gt;, handler: &lt;Function&gt;)。看起来正因为如此,你的状态从一开始就一团糟。此外,您似乎只是添加到 checked 对象,但从未从中删除。
  • 顺便说一句,是否有必要在 vuex 中存储复选框状态?我不会亲自这样做。您可能应该为您的复选框对象添加一个selected 属性,或者只将选定的对象存储在state 中。现在的做法是多余的。
  • 我认为看一下 vuex 文档以了解核心概念并不是多余的。这不是一个巨大的阅读。我在你的问题中看到的有点随机。
  • 我使用的提交语法,称为“Object-Style Commit”,它来自 vuex 官方文档的突变,在我看来更方便,但我检查它是否有问题。
猜你喜欢
  • 1970-01-01
  • 2020-12-22
  • 1970-01-01
  • 2016-05-05
  • 2011-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多