Vuex 动态复选框绑定

Vuex dynamic checkboxes binding

我在使用 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,我不得不显着重构您的代码:

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 link 给你:https://jsfiddle.net/oniondomes/ckj7mgny/