Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vuejs list doesn't reRender while push and change item

Tags:

vue.js

I want push some data to items, and use another list names to reference some data.

  <div v-for="item in items" track-by='$index'>
    {{item.id}} - {{names[item.id].value}}
  </div>

When modify names, list didn't reRender as expect.

This is a demo for my problem.

https://jsfiddle.net/sumy/ep0d28j7/

When click Add ME, I want all the same key with same value. But ...

like image 344
sumy Avatar asked Aug 18 '16 07:08

sumy


4 Answers

Due to the limitation of ES5, Vue.js cannot detect property addition or deletion. Since Vue.js performs the getter/setter conversion process during instance initialization, a property must be present in the data object in order for Vue.js to convert it and make it reactive.

http://vuejs.org/guide/reactivity.html#Change-Detection-Caveats

Use global Vue.set(object, key, value) to make names reactive.

like image 77
sumy Avatar answered Nov 19 '22 04:11

sumy


I was facing the same problem when updating a data array, but I have found a way to force the Vue instance to re-render manually using vm.$forceUpdate() here is the link on the Vue official documentation.

// vue instance
var vm = new Vue({
    el: "#app",
    data: {
        array: ["", "", "", "", "", "", "", "", ""]
    },
    methods: {
        handleClick: function(i) {
            // update your data array
            this.array[i] = "some string";

            // force the instance to be re-rendered
            vm.$forceUpdate();
        }
    }
}
like image 24
Abdelaziz Mokhnache Avatar answered Nov 19 '22 05:11

Abdelaziz Mokhnache


Editing an array item using the square brackets notation won't be picked up by the reactivity system

like image 1
gurghet Avatar answered Nov 19 '22 05:11

gurghet


I found that whatever is being listed with the v-for needs to be wrapped with some type of list, e.g.

Does NOT rerender when 'pages' is updated:

  <v-ons-card v-for="(page, index) of pages" v-bind:key="index"
      @click="push(page.component, page.label)"
  >
     <div class="title">{{ page.label }}</div>
     <div class="content">{{ page.desc }}</div>
  </v-ons-card>

DOES update when 'pages' is updated:

<ul>
      <v-ons-card v-for="(page, index) of pages" v-bind:key="index"
          @click="push(page.component, page.label)"
      >
         <div class="title">{{ page.label }}</div>
         <div class="content">{{ page.desc }}</div>
      </v-ons-card>
</ul>
like image 1
driedler Avatar answered Nov 19 '22 04:11

driedler