Vuex动态复选框绑定 [英] Vuex dynamic checkboxes binding

查看:110
本文介绍了Vuex动态复选框绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用Vuex绑定复选框时遇到问题。在复选框上,我使用带有变量的v模型,该变量具有getter和setter来设置或获取商店中的值,问题是我在商店中获取了错误的数据,并且我不知道是什么引起了问题。复选框绑定到商店属性,并且此属性必须包含来自复选框的ID数组,但是当我多次单击复选框时,它将重写或删除商店值。谁能帮助我了解为什么会这样? 链接到jsFiddle。

I have a problem with binding checkboxes using Vuex. On checkbox I use v-model with variable which has getter and setter to set or get value in store, the problem is that I get wrong data in store and I don't understand what cause the problem. Checkboxes bind to store property and this property must contain array of id's from checkboxes, but when I click checkbox more than one time it rewrite or remove store values. Can anyone help me to understand why does this happens? Link to 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>


推荐答案

好的,假设您要检查以包含选定对象的ID,我不得不对代码进行重大调整:

Okay, assuming you want checked to contain ids of selected objects, I had to restructure your code significantly:

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>

以该代码为例,可以根据需要填充选中的

Using this code as an example, you can populate checked however you want to.

另外,一个jsfiddle为您链接: https://jsfiddle.net/oniondomes/ckj7mgny/

Also, a jsfiddle link for you: https://jsfiddle.net/oniondomes/ckj7mgny/

这篇关于Vuex动态复选框绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆