Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How Do I Get The offsetHeight of a Component Element in Vue.js?

I'm creating a component using Vue.js, and inserting it into the DOM without any problems. Once the element is in the DOM, I'd like to know its rendered height - i.e., I'd like to get its offsetHeight. I can't work out how to do it - I must be missing something really obvious. This is what I've tried:

The HTML:

<!-- vue instance -->
<div id="my-app">

    <my-component></my-component>

</div>

<!-- component template -->
<template id="my-component">
    <h1>Hello World</h1>
    <p>Lorem ipsum dolor sit amet.</h1>
    <pre>{{ myheight }}</pre>
</template>

The Vue Javascript:

Vue.component('my-component',{
    template: '#my-component',
    computed: {
        myheight: function(){
            return this.offsetHeight;
        }
    }
});

Vue({ el: '#my-app' });

But it doesn't work - 'myheight' ends up empty. I thought that maybe the problem was that it might have been trying to generate the computed property before it had been inserted into the DOM, so instead of using a computed property I tried this:

Vue.component('my-component',{
    template: '#my-component',
    data: function(){
        return {
            myheight: 999
        };
    },
    ready: function(){
        this.myheight = this.offsetHeight;
    }
});

Again, it doesn't work - it outputs nothing - and I don't get any errors or warnings in the console.

Then, I thought that maybe this was not an HTMLElement, so I searched the Vue documentation, and found that all Vue instances should have an $el property that points to the HTMLElement - or at least that's how I understood it... So I tried using this.$el.offsetHeight in both examples above, but again with no success.

Can someone point me in the right direction? All assistance is appreciated...

like image 237
Lux Logica Avatar asked Apr 03 '16 08:04

Lux Logica


1 Answers

It looks like the issue lies in your template. You seem to have a fragment instance, meaning that you don't have a top level element that surrounds all the children.

So instead of this, where $el is likely not to refer to what you want…

<!-- component template -->
<template id="my-component">
    <h1>Hello World</h1>
    <p>Lorem ipsum dolor sit amet.</h1>
    <pre>{{ myheight }}</pre>
</template>

…you could wrap your component in a parent element:

<!-- component template -->
<template id="my-component">
    <div class="my-component">
        <h1>Hello World</h1>
        <p>Lorem ipsum dolor sit amet.</p> <!-- and close the tag correctly -->
        <pre>{{ myheight }}</pre>
    </div>
</template>

Then you can get the offset-height using this.$el.offsetHeight:

Vue.component('my-component',{
    template: '#my-component',
    data: function(){
        return {
            myheight: 999
        };
    },
    ready: function(){
        this.myheight = this.$el.offsetHeight;
    }
});

new Vue({ el: '#my-component' });
like image 134
nils Avatar answered Oct 04 '22 16:10

nils