vue-virtual-scroller freeze/unfreeze update

https://www.bountysource.com/issues/64686940-vue-virtual-scroller-isn-t-updating-when-the-data-changes

by Christopher O

HTML

<link rel="stylesheet" href="https://cdn.rawgit.com/Akryum/vue-virtual-scroller/master/dist/vue-virtual-scroller.css" />

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>

<script src="https://cdn.rawgit.com/Akryum/vue-virtual-scroller/master/dist/vue-virtual-scroller.min.js"></script>

<div id="app">
  <my-list :list="list"></my-list><br> {{ list }}
</div>

CSS

.scroller {
  height: 100%;
  border: 1px solid black;
}

.user {
  height: 32%;
  padding: 0 12px;
  display: flex;
  align-items: center;
}

JavaScript

// Although the object can be locally unfrozen, it seems there's no way to replace the single frozen item in Vue's data. It may be possible to clone, unfreeze, update, and replace the entire dict but that's not a good solution

// See here for working unfreeze and how to override the Object.freeze method: https://stackoverflow.com/questions/19293321/opposite-of-object-freeze-or-object-seal-in-javascript/26752410#26752410


console.clear();

Vue.component('recycle-scroller', VueVirtualScroller.RecycleScroller)
Vue.component('my-list', {
  props: ['list'],
  template: `
<recycle-scroller
    class="scroller"
    :items="list"
    :item-height="32"
    keyField="id"
  >
    <div slot-scope="{item}" class="user">
      {{ item }}
    </div>
  </recycle-scroller>
`
})
new Vue({
  el: "#app",
  async created() {

    let id = '0'

    //let item = Object.freeze({
    let item = {
      id,
      text: 'hi ' + id
    }
    //)
    this.$set(this.dict, id, item)

    await timeout()

    //let yoyo = Object.unfreeze(this.dict[id])
    let yoyo = this.dict[id]

    yoyo.text = 'UPDATED'
    this.dict[id] = yoyo
    //this.$set(this.dict, id, yoyo)
  },
  data: {
    dict: {},
  },
  computed: {
    list() {
      return Object.values(this.dict)
    }
  }
})

function timeout(t = 1000) {
  return new Promise(r => setTimeout(r, t))
}