2

Have troubles with component. I’m using vuejs3 via CDN. I have following loop:

<div v-for="product in products">
   <product-tyre-list-card :product="product" :min="product.minimum"></product-tyre-list-card>
</div>

The component ‘product-tyre-list-card’ it self:

export default {
    props: {
        product: Object,
        min: Number
    },
    data() {
        return {
            quantity: this.min
        }
    },
    methods: {
        decrease() {
            if(this.quantity > this.product.minimum) this.quantity--;
        },
        increase() {
            this.quantity++;
        }
    },
    template: `<input v-model="quantity">`
}

So the problem is, when the first array with products is fetched from server - component quantity input is ok. So if we say initial request to server return us products array:

[
    { id: 1, minimum: 2 },
    { id: 2, minimum: 2 },
    { id: 3, minimum: 1 }
] 

Products cards will be displayed correctly, we will see three products cards with input 2,2 and 1. But if then user applies some filters, and we will do request to server, and we will get new products array ie:

[
    { id: 5, minimum: 5 },
    { id: 6, minimum: 5 },
    { id: 7, minimum: 5 }
]

We will see three cards, but input will be from previous request: 2,2 and 1… (but it should be 5, 5, 5). Why is that? What I’m doing wrong?

Thanks!

2 Answers 2

1

Try to set watcher on your min prop or you can use computed property with getter/setter::

const app = Vue.createApp({
  el: '#demo',
  data() {
    return {
      products: [{id: 1, minimum: 2}, {id: 2, minimum: 2}, {id: 3, minimum: 1}] 
    }
  },
  methods: {
    change() {
      this.products = [{id: 5, minimum: 5}, {id: 6, minimum: 5}, {id: 7, minimum: 5}]
    }
  }
})

app.component('product-tyre-list-card', {
  props: {
    product: Object,
    min: Number
  },
  data() {
    return {
      quantity: this.min
    }
  },
  computed: {
    qty: {
      get: function () {
        return this.min;
      },
      set: function (val) {
        this.quantity = val
      },
    },
  },
  /*watch: {
    min(val) {
      this.quantity = val
    }
  },*/
  methods: {
    decrease() {
      if(this.quantity > this.product.minimum) this.quantity--;
    },
    increase() {
      this.quantity++;
    }
  },
  template: `<div><input v-model="qty" />{{ product }}</div>`
})
app.mount('#demo')
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<div id="demo">
  <button @click="change">change</button>
  <div v-for="product in products">
   <product-tyre-list-card :product="product" :min="product.minimum">
   </product-tyre-list-card>
  </div>
</div>

Sign up to request clarification or add additional context in comments.

1 Comment

I thought about this. But is it really the "right way" to do it?
0

I forgot to add key for v-for loop. That's solve the problem.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.