javascript - 推送到数组不会触发 vue 的 react

标签 javascript arrays vue.js vuejs2

我已经知道数组中的编辑对象不适用于 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>

最佳答案

您需要 Vue.set只有当你有 power_generator_groups没有power_generators属性,因为 Vue 无法检测到您何时添加它。
假设您的模板没有问题(您没有显示它),请更改您的 addPowerGenerator方法:

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": []
    }
  )
}

You can see a mockup here我假设 this.item指资源本身。我包括了没有 power_generators 的第三组用于测试的属性。

关于javascript - 推送到数组不会触发 vue 的 react ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56980935/

相关文章:

java - 搜索 200 k 整数数组的数组? java

laravel - 使用 vue.js 自动检查复选框值

javascript - 如何使用两个参数创建 item.split 方法?

c++ - 错误 : Innitializer-string for array of chars is too long c++

javascript - jQuery Sortable 不能拖放

javascript - 检查 JSON 对象是否包含某些值的良好且快速的方法

javascript - vue.js 中的 Intersection Observer 问题

html - HTML元素在Tailwind CSS中的位置

Javascript:解析 html 表

javascript - 如何使用Jquery设置<p>元素的值以及如何使用按钮重置某个对象的所有对象?