Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

184
Visualizações
v-model did not update inside a for-in loop with dynamic object iterations

I'm using an object items to show a list of inputs with v-for.

items is updated when the component mounted, but it only shows two inputs at first.

The third input will display after clicking the button or typing in the input. But the items value doesn't update when the third input changes.

I was wondering

  1. Why the third item did not show at first. (I guess Vue doesn't keep track of the object changes for updating the view?)
  2. Why clicking the button worked
  3. Why the value in the third item did not update.

window.onload = () => {
  new Vue({
    el: '#app',
    data() {
      return {
        show: true,
        items: {
          peter: {
            name: 'Peter',
            value: ''
          },
          kitty: {
            name: 'Kitty',
            value: ''
          }
        },
      }
    },
    watch: {
      show(newVal) {
        console.log('Alert is now ' + (newVal ? 'visible' : 'hidden'))
      }
    },
    mounted() {
      this.items.test = {
        name: 'Test',
        value: ''
      }
    },
    methods: {
      toggle() {
        console.log('Toggle button clicked')
        this.show = !this.show
      },
    }
  })
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <div>
    <button @click="toggle">
      {{ show ? 'Hide' : 'Show' }} Alert
    </button>
    <div v-if="show">
      Hello!
    </div>
    <div v-for="(item,index) in items" :key="index">
      <label>{{item.name}}:</label>
      <input type="text" name="item.name" v-model="items[index].value" />

    </div>
    <div>{{items}}</div>
  </div>
</div>

about 4 years ago · Juan Pablo Isaza
2 Respostas
Responde à pergunta

0

Vue documentation describe this case

Vue does not allow dynamically adding new root-level reactive properties to an already created instance. However, it’s possible to add reactive properties to a nested object using the Vue.set(object, propertyName, value) method:

You can also use the vm.$set instance method, which is an alias to the global Vue.set:

https://v2.vuejs.org/v2/guide/reactivity.html#For-Objects

window.onload = () => {
  new Vue({
    el: '#app',
    data() {
      return {
        show: true,
        items: {
          peter: {
            name: 'Peter',
            value: ''
          },
          kitty: {
            name: 'Kitty',
            value: ''
          }
        },
      }
    },
    watch: {
      show(newVal) {
        console.log('Alert is now ' + (newVal ? 'visible' : 'hidden'))
      }
    },
    mounted() {
      this.$set(this.items, 'test', {
        name: 'Test',
        value: ''
      })
      /*
      this.items.test = {
        name: 'Test',
        value: ''
      }
      */
    },
    methods: {
      toggle() {
        console.log('Toggle button clicked')
        this.show = !this.show
      },
    }
  })
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <div>
    <button @click="toggle">
      {{ show ? 'Hide' : 'Show' }} Alert
    </button>
    <div v-if="show">
      Hello!
    </div>
    <div v-for="(item,index) in items" :key="index">
      <label>{{item.name}}:</label>
      <input type="text" name="item.name" v-model="items[index].value" />

    </div>
    <div>{{items}}</div>
  </div>
</div>

about 4 years ago · Juan Pablo Isaza Relatório

0

Vue has a different way of tracking when it comes to update the UI

Vue uses getters/setters on the data object for mutation tracking. When you execute this.items = [{}, {}, {}, ...];, It will go through the setter of table. In the setter, there's a function to notify the watcher and add this data changes to a queue.

Vue cannot detect the following changes to an array :

  • When you directly set an item with the index, e.g. vm.items[indexOfItem] = newValue
  • When you modify the length of the array, e.g. vm.items.length = newLength

Answer of your Question : In consideration of above two statements, You have to update whole array including the unmodified rows.

about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda