Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vue.js: How to concatenate v-model value

How to make this work:

<div v-for="index in 4">
  <input v-model="'invoice_' + index" >
</div>

just like this:

<div v-for="index in 4">
  <input v-model="invoice_1" >
</div>
like image 374
Syed Avatar asked Mar 08 '23 16:03

Syed


2 Answers

It could be better if you put all the invoices_s variables in a single object and then refer to them by key, something like follows:

new Vue({
  el: '#app',
  data: {
    invoices: {
      invoice_1: '1',
      invoice_2: '2',
      invoice_3: '3',
      invoice_4: '4'
    }
  }
})
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>

<div id="app">
  <div v-for="index in 4">
    <input v-model="invoices['invoice_' + index]">
  </div>
</div>
like image 115
Psidom Avatar answered Mar 21 '23 06:03

Psidom


If you are not able to change how your data is structured, you can access the data object via $data. So you could bind to your invoice properties via $data['invoice_' + index]:

new Vue({
  el: '#app',
  data() {
    return {
      invoice_1: 'a',
      invoice_2: 'b',
      invoice_3: 'c',
      invoice_4: 'd'
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.min.js"></script>
<div id="app">
  <div v-for="index in 4">
    <input v-model="$data['invoice_' + index]" >
  </div>
</div>

However, I agree with Psidom that it would make more sense to change your data structure if you are able to. Although, I would make invoices an array and just access each invoice by the index. This way you don't need to explicitly name each invoice with an index:

new Vue({
  el: '#app',
  data() {
    return {
      invoices: ['a', 'b', 'c', 'd' ]
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.min.js"></script>
<div id="app">
  <div v-for="index in 4">
    <input v-model="invoices[index-1]">
  </div>
</div>

Even better would be to make invoices an array of objects, each with its own id and value. This way you can render the entire array of invoices (via v-for="invoice in invoices") without having to keep track of any indexes. This also allows you to provide a unique key attribute for each rendered element:

new Vue({
  el: '#app',
  data() {
    return {
      invoices: [
        { id: 1, value: 'a' },
        { id: 2, value: 'b' },
        { id: 3, value: 'c' },
        { id: 4, value: 'd' }
      ]
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.min.js"></script>
<div id="app">
  <div v-for="invoice in invoices" :key="invoice.id">
    <input v-model="invoice.value">
  </div>
</div>
like image 42
thanksd Avatar answered Mar 21 '23 04:03

thanksd