Javascript 通过道具将vuex状态传递给组件,并使用v模型或事件更改状态值

Javascript 通过道具将vuex状态传递给组件,并使用v模型或事件更改状态值,javascript,json,vuejs2,vue-component,vuex,Javascript,Json,Vuejs2,Vue Component,Vuex,我有一个模块如何呈现组件并通过道具将vuex的状态传递给组件,目前为止还不错,但我正在将道具绑定到一个复选框列表中并尝试更改其值,但是vuex返回一个错误,告诉我不要在没有变异的情况下变异存储数据,我认为使用代码更容易理解 模块 <template> <div> <modal :visible="modalIsVisible" :data="rules" v-on:openModal="openModal" v-on:

我有一个模块如何呈现组件并通过道具将vuex的状态传递给组件,目前为止还不错,但我正在将道具绑定到一个复选框列表中并尝试更改其值,但是vuex返回一个错误,告诉我不要在没有变异的情况下变异存储数据,我认为使用代码更容易理解

模块

<template>
  <div>
    <modal :visible="modalIsVisible"
      :data="rules"
      v-on:openModal="openModal"
      v-on:submitRules="submitRules">
    </modal>
  <div>
</template>

<script>
import { mapState, mapActions } from 'vuex';

import Modal from './modal/modal.vue';

export default {
  name: 'Module',
  components: {
    Modal,
  },
  data() {
    return {
      modalIsVisible: false
    };
  },
  computed: 
    ...mapState({
      rules(state, getters) {
        return getters['module/rules'];
      },
    }),
  },
  methods: {
    loadRules() {
      this.$store.dispatch('module/getRules');
    },
    async openModal() {
      if (!this.modalIsVisible) {
        await this.loadRules(typeRules);
      }
      this.modalIsVisible = !this.modalIsVisible;
    },
  }
}

</script>
export default {
  rules: [],
};
突变

import { rulesService } from '../../../../services/api/graphql/modules/rules';

export default {
  getRules: async ({ commit }) => {
    const payload = await rulesService.getRules().then(res => res.data.rules);
    commit('setRules', payload);
  },
};
export default {
  setRules: (state, payload) => {
    state.rules = payload;
  },
};
获得者

<template>
    <div>
      <modal :visible.sync="visible">
          <div slot="content">
            <div v-for="group in data" :key="group.name"
               class="neo-form-group">
              <h1 class="policy__title-group--text" v-text="group.name"></h1>
              <div class="neo-form-toggle-list neo-form-toggle-list--inline">
                <div v-for="rule in group.rule" :key="group.title"
                     class="neo-form-toggle-list__item neo-form-toggle neo-form-toggle--checkbox">
                  <input class="neo-form-toggle__field" :id="rule.title" v-model="rule.checked" name="rule"
                     type="checkbox"/>
                  <label class="neo-form-toggle__label" :for="rule.title">
                    {{ rule.title }}
                  </label>
                  <h6 class="neo-text-disabled-options">{{ rule.description }}</h6>
                </div>
              </div>
            </div>
        </div>
      </modal>
    </div>
</template>

<script>
import modal from '@/components/shared/modal/Modal.vue';

export default {
  name: 'ModalRules',
  props: {
    visible: Boolean,
    data: Array,
  },
  components: {
    Modal,
  },
  methods: {
    updateValue(e) {
        //I don't know how to update the property checked of rule    
    },
    setRules() {
      this.$emit('submitRules', { checked: this.data });
    },
    closeModal() {
      this.$emit('openModal');
    },
  }
}

</script>
export default {
  rules: state => state.rules,
};
状态

<template>
  <div>
    <modal :visible="modalIsVisible"
      :data="rules"
      v-on:openModal="openModal"
      v-on:submitRules="submitRules">
    </modal>
  <div>
</template>

<script>
import { mapState, mapActions } from 'vuex';

import Modal from './modal/modal.vue';

export default {
  name: 'Module',
  components: {
    Modal,
  },
  data() {
    return {
      modalIsVisible: false
    };
  },
  computed: 
    ...mapState({
      rules(state, getters) {
        return getters['module/rules'];
      },
    }),
  },
  methods: {
    loadRules() {
      this.$store.dispatch('module/getRules');
    },
    async openModal() {
      if (!this.modalIsVisible) {
        await this.loadRules(typeRules);
      }
      this.modalIsVisible = !this.modalIsVisible;
    },
  }
}

</script>
export default {
  rules: [],
};
JSON模拟

[
  {
    "type": "rules",
    "group": [
      {
        "name": "RuleGroup1",
        "rule": [
          {
            "id": 1,
            "title": "Rule 1",
            "description": "Rule description 1",
            "homonym": false,
            "criticality": "high",
            "checked": false
          },
          {
            "id": 2,
            "title": "Rule 2",
            "description": "Rule description 2",
            "homonym": false,
            "criticality": "high",
            "checked": false
          }
        ]
      },
      {
        "name": "RuleGroup2",
        "rule": [
          {
            "id": 6,
            "title": "Rule 3",
            "description": "Rule description 3",
            "homonym": false,
            "criticality": "high",
            "checked": false
          },
          {
            "id": 7,
            "title": "Rule 4",
            "description": "Rule description 4",
            "homonym": false,
            "criticality": "medium",
            "checked": false
          }
        ]
      },
      {
        "name": "RuleGroup3",
        "rule": [
          {
            "id": 8,
            "title": "Rule 5",
            "description": "Rule description 5",
            "homonym": false,
            "criticality": "high",
            "checked": false
          }
        ]
      },
      {
        "name": "RuleGroup4",
        "rule": [
          {
            "id": 9,
            "title": "Rule 6",
            "description": "Rule description 6.",
            "homonym": false,
            "criticality": "medium",
            "checked": false
          }
        ]
      }
    ]
  }
]
接口

<template>
  <div>
    <modal :visible="modalIsVisible"
      :data="rules"
      v-on:openModal="openModal"
      v-on:submitRules="submitRules">
    </modal>
  <div>
</template>

<script>
import { mapState, mapActions } from 'vuex';

import Modal from './modal/modal.vue';

export default {
  name: 'Module',
  components: {
    Modal,
  },
  data() {
    return {
      modalIsVisible: false
    };
  },
  computed: 
    ...mapState({
      rules(state, getters) {
        return getters['module/rules'];
      },
    }),
  },
  methods: {
    loadRules() {
      this.$store.dispatch('module/getRules');
    },
    async openModal() {
      if (!this.modalIsVisible) {
        await this.loadRules(typeRules);
      }
      this.modalIsVisible = !this.modalIsVisible;
    },
  }
}

</script>
export default {
  rules: [],
};

我不知道如何使用vuex良好实践更改我的复选框状态,这样做vuex会返回一个错误

错误

Error: [vuex] do not mutate vuex store state outside mutation handlers.
我还打算在不访问存储的情况下保留我的组件,将其作为虚拟组件保留,并承担模块状态更改的所有责任


有什么帮助吗?谢谢

要反映商店中更新的复选框更改,你需要在商店中有一个update_rule功能,负责更新规则数组中的规则,如下所示:

商店:

  mutations:
    {
      UPDATE_RULE(state, payload) // payload will hold the rule id and updated value
      {
        // payload is {id: 2, value: false} 
        state.rules.forEach(function(element){     
          if(element.rule.filter(item => item.id == payload['id')).length >0)
          {
            element.rules.filter(item => item.id == payload['id'])[0]['checked'] = payload['value']
          }      
        })

      }
    }

    ...
     actions: 
    {
      update_rule(context, payload) {
        context.commit('UPDATE_RULE', payload)
      },

    }
<div v-for="rule in group.rule" :key="group.title" >
    <input :id="rule.title" v-model="rule.checked" name="rule" v- 
            on:change="update_rule_val(rule.id, $event.target.value)" 
            type="checkbox"/>
                  <label :for="rule.title">
                    {{ rule.title }}
                  </label>
                  <h6>{{ rule.description }}</h6>
                </div>

...
methods: {
    update_rule_val(id,val){
      this.update_rule({id: id, value: val})
    },
    ...mapActions(["update_rule"]),
组件:

  mutations:
    {
      UPDATE_RULE(state, payload) // payload will hold the rule id and updated value
      {
        // payload is {id: 2, value: false} 
        state.rules.forEach(function(element){     
          if(element.rule.filter(item => item.id == payload['id')).length >0)
          {
            element.rules.filter(item => item.id == payload['id'])[0]['checked'] = payload['value']
          }      
        })

      }
    }

    ...
     actions: 
    {
      update_rule(context, payload) {
        context.commit('UPDATE_RULE', payload)
      },

    }
<div v-for="rule in group.rule" :key="group.title" >
    <input :id="rule.title" v-model="rule.checked" name="rule" v- 
            on:change="update_rule_val(rule.id, $event.target.value)" 
            type="checkbox"/>
                  <label :for="rule.title">
                    {{ rule.title }}
                  </label>
                  <h6>{{ rule.description }}</h6>
                </div>

...
methods: {
    update_rule_val(id,val){
      this.update_rule({id: id, value: val})
    },
    ...mapActions(["update_rule"]),

{{rule.title}
{{rule.description}}
...
方法:{
更新规则值(id,val){
此.update_规则({id:id,value:val})
},
…映射操作([“更新规则]),

当您更新规则时,是否要更新存储区内的数据?因为您的存储区是真相的来源,应该与任何更改同步。是的,我要更新存储区内的数据。