推送到数组不会触发vue的反应性

时间:2019-07-11 02:39:14

标签: arrays vue.js

我已经知道数组中的对象由于其功能有限而不能用于vue.js,并且基于我使用vue.set读取的内容应该可以轻松解决此问题,但是我很难使它起作用。

这是我的示例数据。父对象称为资源,资源内部有power_generator_groups,power_generator_groups内部是power_generators。

{
  "id": 5,
  "bg_member_id": 1,
  "code": "G0633",
  "name": "namex1",
  "power_generator_groups": [
    {
      "id": 1,
      "resource_id": 5,
      "code": "GC033",
      "power_generators": [
        {
          "id": 1,
          "power_generator_group_id": 1,
          "code": "XXXXX",
          "name": "test",
          "contract_number": "00000003",
          "supply_max": 1000,
        },
        {
          "id": 2,
          "power_generator_group_id": 1,
          "code": "XXXXX",
          "name": "test",
          "contract_number": "00000003",
          "supply_max": 1000,
        },
        {
          "id": 3,
          "power_generator_group_id": 1,
          "code": "XXXXX",
          "name": "test",
          "contract_number": "00000003",
          "supply_max": 1000,
        }
      ]
    },
    {
      "id": 2,
      "resource_id": 5,
      "code": "GC033",
      "contract_number": "065C001",
      "power_generators": [
        {
          "id": 4,
          "power_generator_group_id": 2,
          "code": "XXXXX",
          "name": "test",
          "contract_number": "00000003",
          "supply_max": 1000,
        }
      ]
    }
  ]
}

这是我的Vue文件

<template lang="pug">
  .wrapper
    .animated.fadeIn
      b-container(fluid='')
        b-row.my-1
          b-col(sm='3')
            label(:for='`type-key`') companyName
          b-col(sm='9')
            b-form-select(v-model='item.bg_member_id' :options="companyList")
          b-col(sm='3')
            label(:for='`type-key`') code
          b-col(sm='9')
            b-form-input(v-model='item.code')

        b-button(size='sm', @click='addPowerGeneratorGroup', variant="primary")
          | Add power_generator_group
        template(v-for='(group, group_index) in item.power_generator_groups')
          b-card(
            header-tag="header"
            footer-tag="footer"
            )
            div(slot="header")
              i.fa.fa-align-justify
              strong power_generator_groups
              button.btn.btn-default.btn-sm(type='button' @click='deletePowerGeneratorGroup(group_index)')
                span.fa.fa-trash-o
            div
            b-row.my-1
              b-col(sm='3')
                label(:for='`type-key`')
                  | code
              b-col(sm='9')
                b-form-input(v-model='group.code')
              b-col(sm='3')
                label(:for='`type-key`') group name
              b-col(sm='9')
                b-form-input(v-model='group.name')
              b-col(sm='3')
                label(:for='`type-key`') contract number
              b-col(sm='9')
                b-form-input(v-model='group.contract_number')
              b-container.bv-example-row(fluid='')
                b-button(size='sm', @click='addPowerGenerator(group_index)', variant="primary")
                  | add power_generator
              b-card(
                header-tag="header"
                footer-tag="footer"
                )
                div(slot="header")
                  i.fa.fa-align-justify
                  strong power_generators
                  b-table(small v-bind:item="group.power_generators" v-bind:fields="fields" fixed responsive)
                    template(v-for="field in fields" :slot="field.key" slot-scope="contract")
                      template(v-if="field.key == 'actions'")
                        b-button(size='sm', @click='deletePowerGenerator(group_index, contract.index)', variant="primary")
                          | Del
                      template(v-else)
                        b-form-input(:type='types[field.key]' v-model = 'contract.item[field.key]')


        b-button(size='sm', @click='save', variant="primary")
          | Save
</template>

<script>
import Vue from 'vue';
  export default {
    props: {
      item: {
        type: Object,
        required: true,
        default: () => {
        }
      },
      companyList: Array
    },
    data() {
      return {
        companyId: null,
        code: null,
        name: null,
        contract_number: null,
        fields: [
          {key: 'actions', label: '' },
          {key: 'code', label: 'code', sortable: true, sortDirection: 'desc'},
          {key: 'name', label: 'name', sortable: true, class: 'text-center'},
          {key: 'contract_number', label: 'contractNo'},
          {key: 'supply_max', label: 'maxunit'}
        ],
        types: {
          code: 'text',
          name: 'text',
          contract_number: 'text',
          supply_max: 'number'
        },
        items: 
        {}
      }
    },
    mounted() {
    },
    computed: {},
    methods: {
    addPowerGenerator(index) {
      console.log(index)
      console.log(this.item)
      const pgg = this.item.power_generator_groups[index];
      const pgs = pgg.power_generators || Vue.set(pgg, 'power_generators', []);
      pgs.push(
        {
          "code": "",
          "name": "",
          "contract_number": "",
          "supply_max": "",
        }
      )
    },
    addPowerGeneratorGroup() {
      const pggs = this.item.power_generator_groups || Vue.set(this.item, 'power_generator_groups', []);
      pggs.push(
        {
          "resource_id": this.item.id,
          "name": "",
          "code": "",
          "contract_number": "",
          "power_generators": []
        }
      )
    },
      deletePowerGenerator(group_index, field_index) {
        this.item.power_generator_groups[group_index].power_generators.splice(field_index, 1);
      },
      deletePowerGeneratorGroup(group_index) {
        this.item.power_generator_groups.splice(group_index, 1);
      },
      save: function () {
        this.$parent.save(this.item)
      }
    }
  }
</script>

1 个答案:

答案 0 :(得分:0)

仅当拥有Vue.set不具有power_generator_groups属性的power_generators时,您才需要addPowerGenerator,因为否则Vue无法检测到何时添加它。  假设模板没有问题(您没有显示模板),请更改您的addPowerGenerator(index) { console.log(index) console.log(this.item) const pgg = this.item.power_generator_groups[index]; const pgs = pgg.power_generators || Vue.set(pgg, 'power_generators', []); pgs.push( { "code": "", "name": "", "contract_number": "", "supply_max": "", } ) } 方法:

Vue.set

pgs返回您刚刚创建的属性,在这种情况下,addPowerGeneratorGroup() { const pggs = this.item.power_generator_groups || Vue.set(this.item, 'power_generator_groups', []); pggs.push( { "resource_id": this.item.id, "name": "", "code": "", "contract_number": "", "power_generators": [] } ) } 包含正确的引用。

对您在其中编辑的新方法执行相同的操作:

this.item

You can see a mockup here,我假设power_generators是指资源本身。我加入了第3组,该组没有if (isset($_POST['submit'])) { //here goes your validations } 属性用于测试。