vuejs
vuejs

Reputation: 11

Vue slot-scope with v-for, data changed but not re-rendered

I have a question while I'm studying vuejs2

I made an example with slot-scope && v-for, but it has an error which I can't understand.

Here is example code https://jsfiddle.net/eywraw8t/6839/

app.vue

<template id="list-template">
  <div>
    <ul>
      <slot name="row" v-for="item in list" v-bind=item />
    </ul>
  </div>
</template>

<div id="app">
  <list-component :list="list">
    <li slot="row" slot-scope="item">
      <a href="#" @click.prevent="h(item)">{{item.name}}</a>
    </li>
  </list-component>
</div>
Vue.component('list-component', {
  template: '#list-template',
   props: {
      list: {
        type: Array
      }
   }
});

new Vue({
  el: '#app',
  data () {
    return {
        list: [
        {id: 1, name: 'Apple'},
        {id: 2, name: 'Banana'},
        {id: 3, name: 'Cherry'},
        {id: 4, name: 'Durian'},
        {id: 5, name: 'Eggplant'}
      ]
    }
  },
  methods: {
    h (item) {
      item.name = item.name.toUpperCase()
      console.log('Changed!')
      console.log(item)
    }
  }
});

Strange thing is, the method 'h' is triggered and then, the console said 'Changed!' and data also changed but, the view is not re-rendered.

What am I missing? I think slot-scoped object data is not referencing the original object data.

What should I do to modify the original data?

Thanks for reading this question.

Upvotes: 1

Views: 2544

Answers (1)

Vamsi Krishna
Vamsi Krishna

Reputation: 31362

You are directly trying to modify the value of an item in an array. Due to some limitations vue cannot detect such array modifications.

So update your code to use vm.$set() to make chamges to the array item.

methods: {
    h (item) {
      let i = this.items.findIndex((it) => it.id === item.id);
      this.$set(this.list, i, {...item, name: item.name.toUpperCase()});
    console.log(item.id)
  }

Here is the updated fiddle

Upvotes: 1

Related Questions