Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic v-model using v-for value + string in VueJS 2

In my JavaScript I have:

data: {
    rooms: [
         {type: 'single'},
         {type: 'double'}
         ...
    ],
    selectedSingle: 0,
    selectedDouble: 0,
    ...
},
computed: {
    capitalize: function(string) {
        return string.charAt(0).toUpperCase() + string.slice(1);
    }
}

In HTML I have:

<li v-for="(room, index) in rooms">
    <input type="number" v-model="'selected' + capitalize(room.type)">
</li>

The problem is that I can't find a way to access my models in this way, and the only way I see now is to destroy the v-for and make it manually, but it's not the best solution because I have many "rooms". Any ideas are welcome.

like image 841
Spidey Avatar asked Apr 18 '18 14:04

Spidey


2 Answers

You are attempting to access a data property via string. For that you can use the object access property notation (obj['propname']) using $data as the object:

<input type="number" v-model="$data['selected' + capitalize(room.type)]">

Plus your computed should really be a method:

  methods: {                                // changed from computed to method
    capitalize: function(string) {

Demo:

new Vue({
  el: '#app',
  data: {
    rooms: [
      {type: 'single'},
      {type: 'double'}
    ],
    selectedSingle: 111,
    selectedDouble: 222,
  },
  methods: {                                // changed from computed to method
    capitalize: function(string) {
      return string.charAt(0).toUpperCase() + string.slice(1);
    }
  }
})
<script src="https://unpkg.com/vue"></script>

<div id="app">
  <ul>
    <li v-for="(room, index) in rooms">
      <input type="number" v-model="$data['selected' + capitalize(room.type)]">
    </li>
  </ul>
</div>
like image 159
acdcjunior Avatar answered Oct 06 '22 00:10

acdcjunior


For people who are using Vue 3, use this instead of $data.

For example:

import { reactive, createApp } from 'vue';

createApp({
  setup() {
    const state = reactive({
      propertyA: 'valueA',
      propertyB: 'valueB',
    });
    return state;
  };
});
<input v-for="p in ['propertyA', 'propertyB']" v-model="this[p]">
like image 38
Yi Feng Xie Avatar answered Oct 06 '22 01:10

Yi Feng Xie