meteor-vue / vue-meteor

🌠 Vue first-class integration in Meteor
897 stars 112 forks source link

Render of margins of children of non-block elements is delayed #289

Open vbgm opened 6 years ago

vbgm commented 6 years ago

When trying to get the height of elements that are anything else than display:block, using stylesheet set within .vue component file, the height returned immediately and after $nextTick is not correct, as if the render of component’s style is delayed.

For example:

<template>

  <div class='test'>
    <div class='inner'>
      test
    </div>
  </div>

  <!-- <div style='display: flex; background: red;'>
    <div style='margin: 50px;'>
      test
    </div>
  </div> -->

</template><script>

  export default {
    name: 'Test',
    mounted () {
      console.log('Height 1', this.$el.clientHeight)
      this.$nextTick(() => {
        console.log('Height 2', this.$el.clientHeight)
      })
      setTimeout(() => {
        console.log('Height 3', this.$el.clientHeight)
      }, 300)
    }
  }

</script><style>

  .test {
    display: flex;
    background: red;
    /*display: table-cell;*/
    /*display: inline-block;*/
  }

  .inner {
    margin: 50px;
  }

</style>

The result of the example is that the 'Height 1' and 'Height 2' return 18px whereas 'Height 3' returns 118px (like the styles are applied only after some time).

This happens only in Meteor with vue-component and not the case with clean Vue installation (checked here: https://github.com/vuejs/vue-loader/issues/1133), where all 'Heights' would return 118px.

There seem to be 2 workarounds:

  1. Use inline styles (as in the commented section of the example)
  2. Use external imported stylesheet

In both workaround cases all the 'Heights' would be returned as 118px.

This is actually rather nasty thing, as since I am dealing with many absolute positioned elements, not being able to reliably get rendered parameters make the whole hierarchy of components shaky.

Maybe there is any forgotten ‘option’ somewhere to prevent rendering the component before it’s styles have been loaded? Or any option to pre-import the style into the component?

vbgm commented 6 years ago

@Akryum when you have a minute, could you please confirm if this is the actual bug? Or there might be another way/workaround? This is related not only to margins but whenever trying to get proper height of elements. Currently setting 50ms timeouts instead of proper $nextTick is very annoying and unreliable.

Akryum commented 6 years ago

That's because style is injected by JavaScript in development. In production, it will be in a CSS file and loaded before the JavaScript.