Home > Mobile >  Vue.js UI does not update the state on window reload
Vue.js UI does not update the state on window reload

Time:07-05

I have the following code structure (simplified):

<template v-for="tile of layer.data">
    <VueDragResize :x="calculatePositionX(tile)">
        <h2 :style="{'font-size':calculateFontSize(tile)   'px'}">Test</h2>
    </VueDragResize>
</template>  

The :x="calculatePositionX(tile) and :style="{'font-size':calculateFontSize(tile) 'px'}" values are dynamic. I want to change these values on window resize.

To achieve this I do this: (too keep it simple I want to show you only the calculatePositionX example).

mounted() {
    window.addEventListener('resize', this.onResize);
},
beforeDestroy() {
    window.removeEventListener('resize', this.onResize)
},
methods: {
    onResize(event) {
      this.calculatePositionX(null);
    },
    calculatePositionX(tile) {
        if (!tile) {
            tile = this.cachedTile;
        }
        
        this.cachedTile = tile;
        let x = tile.boxPositionX;
        let parentWidth = tile.boxPositionParentWidth;
        let currentParentWidth = this.$refs.builderLayer.clientWidth;
        
        if (parentWidth == currentParentWidth) {
            return x;
        }
        console.log(currentParentWidth * x / parentWidth); // Returns different result as the initial, but the state is not updating
        return currentParentWidth * x / parentWidth;        
    },
}
data() {
  return {
    cachedTile: Object,
  }
},

The console.log(currentParentWidth * x / parentWidth); returns a different result as the initial, but the state is not updating on the UI.

What can be the issue here? I also tried to save the new value as variable into the store and return the store result. Without success.

What do you think?

CodePudding user response:

You defined calculatePositionX on the Vue instance itself.

Move it inside methods and it will work.


Side note: you might want to replace cachedTile: Object with cachedTile: {} in data.

CodePudding user response:

In the OP code, you call calculatePositionX on resize, but ignore the return. The template won't know to update on the resize, but it will if dependent data changes.

Rather than returning the result of the resize calculation, have your calculatePositionX method change the state, then, let vue reactive getters do their job in the template. Refer to x in data (which is set by the slightly modified calculatePositionX)

<template v-for="tile of layer.data">
    <VueDragResize :x="x">
        <h2 :style="style(tile)">Test</h2>
    </VueDragResize>
</template>  


mounted() {
    window.addEventListener('resize', this.onResize);
    this.onResize();
},
beforeDestroy() {
    window.removeEventListener('resize', this.onResize)
},
methods: {
    onResize(event) {
      this.calculatePositionX(null);
    },
    calculatePositionX(tile) {
        if (!tile) {
            tile = this.cachedTile;
        }
        
        this.cachedTile = tile;
        let x = tile.boxPositionX;
        let parentWidth = tile.boxPositionParentWidth;
        let currentParentWidth = this.$refs.builderLayer.clientWidth;
        
        if (parentWidth == currentParentWidth) {
            this.x = x;
            return;
        }
        console.log(currentParentWidth * x / parentWidth); 
        this.x = currentParentWidth * x / parentWidth;        
    },
    style(tile) {
      return {'font-size':calculateFontSize(tile)   'px'}
    }
}
data() {
  return {
    x: 0, // will get initialized in mounted
    cachedTile: Object,
  }
},
  • Related