1π
Can we have two versions of products
? One for the server, one for v-models.
var server_products = [
{ id: 1, name: "Prod 1", stock: 5 },
{ id: 2, name: "Prod 2", stock: 6 }
]
//...
data: () => ({
products = server_products
})
updateStock(stock, productId) {
server_products.forEach((product) => {
if(product.id === productId && stock !== product.stock){
product.stock = stock
// do ajax
}
})
},
//...
If not than you can use vueβs watch
property so vue finds changes to the array for you.
//...
data: () => ({
products: [
{ id: 1, name: "Prod 1", stock: 5 },
{ id: 2, name: "Prod 2", stock: 6 }
]
}),
watch: {
'products': {
handler: function(newValue) {
// do ajax
},
deep: true
}
}
//...
- [Vuejs]-Vue 3 β How to set Typescript object to one of many interfaces?
- [Vuejs]-How to refer to a private variable declared in <script> in <script setup>
1π
Personally this feels like a higher level question to which your flow of product editing needs tweaking. Here is what I can think of:
- User enters all the information.
- User hits submit button.
- Check whether of not the stock count is empty or 0.
- Return an error message if it is.
- Submit and update otherwise.
It might be worth looking into vuelidate that handles such validation in JavaScript. Meanwhile, we are also coming up with a tool called CRUDS DS (a WIP) that handles such situation with ease.
π€CRUD DS
1π
The best way is to create a ProductComponent
and watch every product separately inside its own component, as shown below:
Product.vue
<ProductComponent
v-for="product in products"
:product="product"
:key="product.id" />
ProductComponent.vue
<template>
<tr>
<td>{{ product.name }}</td>
<td>
<input
type="text"
class="form-control"
v-model="product.price"
@paste.prevent
/>
</td>
<td>
<input
type="text"
class="form-control"
maxlength="999"
v-model="product.stock"
@paste.prevent
@keypress="onlyNumber($event)"
@blur="updateStock($event.target.value, product.id)"
/>
</td>
</tr>
</template>
<script>
export default {
props: {
product: {
type: Object,
default: {},
},
},
data: () => ({ actual_stock: "" })
// this is for handle stock cannot be empty or GTE:0
// also you dont need handleInputStock anymore
watch: {
product: {
handler(val) {
this.actual_stock = val.stock;
},
immediate: true,
},
"product.stock": function (newVal, oldVal) {
this.product.stock = +newVal;
},
},
methods: {
updateStock(stock, productId) {
if (!(stock == this.actual_stock)) {
// do ajax
}
}
}
}
</script>
If you want to handle it on parent side, you may use $emit
to send an event upwards.
π€Aslam H
- [Vuejs]-VueJs β Vuex β Change a state
- [Vuejs]-How to display a default fontawesome icon when icon is not registered ? (Vue, Angular or React)
Source:stackexchange.com