I am attempting to add objects into an array I declared in Vue instance data object. I can set the values in the state's purchase object, but when I push data into the orders queue array, the empty array is not populated. The function is being triggered, but the array does not update.
Here is my form:
<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> Q U E U E</span>
</button>
</div>
</form>
And here is my 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 );
}
}
});
Could someone please explain what & why it is happening?
The push()
method ought to add purchase
objects to the queue
array, but as @FK82 pointed out in his comment, push()
is adding multiple references to the same purchase
object. This means that if you change the object by increasing the quantity
, every purchase
's quantity
property will be updated.
You can give that a try here:
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>
Instead of push()
ing a reference to the same purchase
object, try creating a shallow copy with Object.assign({}, this.purchase)
or by using the spread operator. Here's an example that uses the spread operator and then push()
es the copy onto the 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>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.