Ahmed Rafik Ibrahim
Ahmed Rafik Ibrahim

Reputation: 547

Vue.js - Recompute computed property in a component

I searched this problem a lot with no direct answer found. I have a computed property that depends also on the window height so I need it to be recomputed every time the window is resized. Tried using $forceUpdate() but I think it doesn't work with components. Here is my component :

Vue.component('trades-component', {

  mixins: [tradingMixin],

  created: function() {
    var that = this;
    // recompute visible trades if window resized
    $( window ).on( "resize", function() {
      that.$forceUpdate();
    });
    $( window ).resize();
  },

  computed: {

    visibleTradesCount: function() {
      var colOffset = $(".left-col").offset();
      var colHeight = $(".left-col").height();
      var tableOffset = $(".left-col #trade-history table").offset();
      var tableHeight = colHeight - (tableOffset.top - colOffset.top) - this.rowHeight;
      return Math.floor(tableHeight / this.rowHeight)
    }
  }
})

I know possible workarounds but want to know if there is a way to force recomputing a particular property or all computed properties in components.

Upvotes: 5

Views: 12877

Answers (2)

Bill Criswell
Bill Criswell

Reputation: 32921

You can't use a computed property for this because you're not updating anything Vue is observing. You can move visibleTradesCount from computed to methods and do:

$(window).on('resize', this.visibleTradesCount).resize()

Just make sure to debounce the resize event. Also, you should really look into accomplishing this without JavaScript.

Upvotes: 3

Richard Matsen
Richard Matsen

Reputation: 23483

This isn't as clean as @BillCriswell's answer, but if your computed has other dependencies that trigger a refresh (e.g a data change), you may want to stick with a computed.

You can force a recalc on resize by using data properties for window width and height, and adding a reference to them in your computed property.

data: function () {
  return { 
    windowWidth: 0,
    windowHeight: 0
  }
}
created: function() {
  var that = this;
  $( window ).on( "resize", function() {
    that.windowWidth =  window.innerWidth;
    that.windowHeight = window.innerHeight;
  });
  $( window ).resize();
},
computed: {
  visibleTradesCount: function() {
    const x = this.windowWidth;
    const y = this.windowHeight;
    ...

Note, you may need to $(window).off("resize" in beforeDestroy().

Upvotes: 5

Related Questions