I would like to force the UI to update midway through an event loop cycle.
Vue.nextTick
Vue.nextTick seems to provide you with an updated version of vm.$el, but doesn't actually cause the UI to update.
CodePen: https://codepen.io/adamzerner/pen/RMexgJ?editors=1010
HTML:
<div id="example">
  <p>Value: {{ message }}</p>
  <button v-on:click="change()">Change</button>
</div>
JS:
var vm = new Vue({
  el: '#example',
  data: {
    message: 'A'
  },
  methods: {
    change: change
  }
})
function change () {
  vm.message = 'B';
  // vm.$el.children[0].textContent === "Value: A"
  Vue.nextTick(function () {
    // vm.$el.children[0].textContent === "Value: B"
    // but the UI hasn't actually updated
    for (var i = 0; i < 10000000; i++) {}
    vm.message = 'C';
  });
}
vm.$forceUpdate
vm.$forceUpdate doesn't appear to do anything at all.
- It doesn't appear to change the value of vm.$el.
- It doesn't appear to update the UI.
CodePen: https://codepen.io/adamzerner/pen/rdqpJW?editors=1010
HTML:
<div id="example">
  <p>Value: {{ message }}</p>
  <button v-on:click="change()">Change</button>
</div>
JS:
var vm = new Vue({
  el: '#example',
  data: {
    message: 'A'
  },
  methods: {
    change: change
  }
})
function change () {
  vm.message = 'B';
  // vm.$el.children[0].textContent === "Value: A"
  vm.$forceUpdate();
  // vm.$el.children[0].textContent === "Value: A" still
  // and the UI hasn't actually updated
  for (var i = 0; i < 10000000; i++) {}
  vm.message = 'C';
}
v-bind:key
v-bind:key also doesn't appear to do anything at all:
- It doesn't appear to change the value of vm.$el.
- It doesn't appear to update the UI.
Codepen: https://codepen.io/adamzerner/pen/WzadKN?editors=1010
HTML:
<div id="example">
  <p v-bind:key="message">Value: {{ message }}</p>
  <button v-on:click="change()">Change</button>
</div>
JS:
var vm = new Vue({
  el: '#example',
  data: {
    message: 'A'
  },
  methods: {
    change: change
  }
})
function change () {
  // vm.$el.children[0].textContent === "Value: A"
  vm.message = 'B';
  // vm.$el.children[0].textContent === "Value: A" still
  // and the UI hasn't actually updated
  for (var i = 0; i < 10000000; i++) {}
  vm.message = 'C';
}
computed
Using a computed property, as this popular answer recommends, also doesn't appear to do anything:
- It doesn't appear to change the value of vm.$el.
- It doesn't appear to update the UI.
CodePen: https://codepen.io/adamzerner/pen/EEdoeX?editors=1010
HTML:
<div id="example">
  <p>Value: {{ computedMessage }}</p>
  <button v-on:click="change()">Change</button>
</div>
JS:
var vm = new Vue({
  el: '#example',
  data: {
    message: 'A'
  },
  computed: {
    computedMessage: function () {
      return this.message;
    },
  },
  methods: {
    change: change
  }
})
function change () {
  // vm.$el.children[0].textContent === "Value: A"
  vm.message = 'B';
  // vm.$el.children[0].textContent === "Value: A" still
  // and the UI hasn't actually updated
  for (var i = 0; i < 10000000; i++) {}
  vm.message = 'C';
}
Promise (added in edit)
Using promises doesn't work either.
CodePen: https://codepen.io/adamzerner/pen/oqaEpV?editors=1010
HTML:
<div id="example">
  <p>Value: {{ message }}</p>
  <button v-on:click="change()">Change</button>
</div>
JS:
var vm = new Vue({
  el: '#example',
  data: {
    message: 'A'
  },
  methods: {
    change: change
  }
})
function change () {
  // vm.$el.children[0].textContent === "Value: A"
  vm.message = 'B';
  // vm.$el.children[0].textContent === "Value: A" still
  // and the UI hasn't actually updated
  var promise = new Promise(function (resolve, reject) {
    for (var i = 0; i < 10000000; i++) {}
    resolve();
  });
  promise.then(function () {
    vm.message = 'C';
  });
}
setTimeout
setTimeout is the only thing that seems to work. But it only works consistently when the delay is 100. When the delay is 0, it works sometimes, but doesn't work consistently.
- vm.$elupdates.
- The UI updates.
CodePen: https://codepen.io/adamzerner/pen/PRyExg?editors=1010
HTML:
<div id="example">
  <p>Value: {{ message }}</p>
  <button v-on:click="change()">Change</button>
</div>
JS:
var vm = new Vue({
  el: '#example',
  data: {
    message: 'A'
  },
  methods: {
    change: change
  }
})
function change () {
  // vm.$el.children[0].textContent === "Value: A"
  vm.message = 'B';
  setTimeout(function () {
    // vm.$el.children[0].textContent === "Value: B"
    // the UI has updated
    for (var i = 0; i < 10000000; i++) {}
    vm.message = 'C';
  }, 100);
}
Questions
- Why don't Vue.nextTick,vm.$forceUpdate,v-bind:key, or computed properties work?
- Why does setTimeoutwork inconsistently when the delay is0?
- setTimeoutseems hacky. Is there a "propper" way to force a UI update?
 
     
     
     
    