web-dev-qa-db-fra.com

Comment puis-je envoyer des éléments dans un tableau de l'objet de données dans Vuejs? Vue semble ne pas regarder la méthode .Push ()

J'essaie d'ajouter des objets dans un tableau que j'ai déclaré dans un objet de données d'instance Vue. Je peux définir les valeurs dans l'objet d'achat de l'état, mais lorsque je transmet des données dans le tableau de la file d'attente des commandes, le tableau vide n'est pas rempli. La fonction est en cours de déclenchement, mais le tableau ne se met pas à jour.

Voici mon formulaire:

<form
  v-on:submit.prevent="queuePurchase"
  class="form-inline row"
  id="order-creation-form"
  method="POST"
>

  @csrf
  <autocomplete-field
    sizing="col-xs-12 col-sm-3 col-md-3"
    name="customer"
    label="Customer"
    :data="{{ json_encode($customers) }}"
    v-on:setcustomer="setCustomer($event)"
  ></autocomplete-field>

  <div class="col-xs-12 col-sm-3 col-md3 form-group d-flex flex-column align-items-start">
    <label for="phone">Product</label>
    <select
      v-model="purchase.product"
      class="form-control w-100"
      name="product"
      aria-describedby="productHelpBlock"
      required
    >
      @foreach ($products as $product)
        <option :value="{{ json_encode($product) }}">
          {{ $product->name }}
        </option>
      @endforeach
    </select>
    <small id="productHelpBlock" class="form-text text-muted">
      Select a product
    </small>
  </div>

  <div class="col-xs-12 col-sm-3 col-md-3 form-group d-flex flex-column align-items-start">
    <label for="phone">Quantity</label>
    <input
      v-model="purchase.quantity"
      type="number"
      min="1"
      name="product"
      class="form-control w-100"
      aria-describedby="productHelpBlock"
      required
    >
    <small id="productHelpBlock" class="form-text text-muted">
      Product quantity
    </small>
  </div>

  <div class="form-group">
    <button type="submit" class="btn btn-success icon-button d-flex">
      <i class="material-icons">add</i>
      <span>&nbsp;&nbsp;  Q U E U E</span>
    </button>
  </div>
</form>

Et voici mon javascript:

require("./bootstrap");
window.Vue = require("vue");

Vue.component("queue-table", require('./components/QueueTable.vue'));
Vue.component("autocomplete-field", require('./components/AutocompleteField.vue'));

const purchaseApp = new Vue({
    el: "#purchase-app",

    data() {
        return {
            queue: [],
            purchase: {
                product: null,
                customer: null,
                quantity: null
            }
        }
    },

    methods: {
        setCustomer: function(customerObj) {
            this.purchase.customer = customerObj;
        },

        queuePurchase: function() {
            this.queue.Push( this.purchase );
        }
    }
});

Quelqu'un pourrait-il s'il vous plaît expliquer quoi et pourquoi cela se passe?

4
Howard Mkongo

La méthode Push() doit ajouter des objets purchase au tableau queue, mais comme l'a souligné @ FK82 dans son commentaire, Push() ajoute plusieurs références au même objet purchase. Cela signifie que si vous modifiez l'objet en augmentant la valeur quantity, chaque propriété purchase's quantity sera mise à jour.

Vous pouvez essayer ça ici:

const exampleComponent = Vue.component("example-component", {
  name: "exampleComponent",
  template: "#example-component",
  data() {
    return {
      queue: [],
      purchase: {
        product: null,
        customer: null,
        quantity: null
      }
    };
  },
  methods: {
    queuePurchase() {
      this.queue.Push( this.purchase );
    }
  }
});

const page = new Vue({
  name: "page",
  el: ".page",
  components: {
    "example-component": exampleComponent
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.2.4/vue.min.js"></script>
<template id="example-component">
  <div>
    <p>The Queue has {{ this.queue.length }} items.</p>
    <input
      v-model="purchase.quantity"
      type="number"
      min="1"
      name="product"
      placeholder="Quantity"
    >
    <button @click="queuePurchase">
      Add to Queue
    </button>
    <pre>{{ JSON.stringify(this.queue, null, 2) }}</pre>
  </div>
</template>

<div class="page">
  <example-component></example-component>
</div>

Au lieu de Push()ing une référence au même objet purchase, essayez de créer une copie superficielle avec Object.assign({}, this.purchase) ou en utilisant l'opérateur spread. Voici un exemple qui utilise l'opérateur spread, puis Push()es la copie sur la queue:

const exampleComponent = Vue.component("example-component", {
  name: "exampleComponent",
  template: "#example-component",
  data() {
    return {
      queue: [],
      purchase: {
        product: null,
        customer: null,
        quantity: null
      }
    };
  },
  methods: {
    queuePurchase() {
      this.queue.Push({...this.purchase});
    }
  }
});

const page = new Vue({
  name: "page",
  el: ".page",
  components: {
    "example-component": exampleComponent
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.2.4/vue.min.js"></script>
<template id="example-component">
  <div>
    <p>The Queue has {{ this.queue.length }} items.</p>
    <input
      v-model="purchase.quantity"
      type="number"
      min="1"
      name="product"
      placeholder="Quantity"
    >
    <button @click="queuePurchase">
      Add to Queue
    </button>
    <pre>{{ JSON.stringify(this.queue, null, 2) }}</pre>
  </div>
</template>

<div class="page">
  <example-component></example-component>
</div>

2
Travis Hohl