Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access $el inside a computed property

Tags:

vue.js

vuejs2

I'm trying to access this.$el.offsetTop in a computed property, but get the error:

Cannot read property 'offsetTop' of undefined

How can I access the offsetTop of the component in a computed method? if this is not possible then is there an alternative?

Component:

<template>
    <div :class="{ 'active' : test }"></div>
</template>
<script>
export default {

    computed: {

        test() {
           console.log(this.$el.offsetTop);
        }
    }
}
</script>
like image 306
panthro Avatar asked Sep 27 '17 15:09

panthro


2 Answers

Here's what I did to solve this problem:

I set an el property to null in the component's data, and in the mounted hook, I set this.el to this.$el. Then, in the computed property, I check this.el before trying to access its properties to avoid an error during the first render. So, in the context of your example we'd have:

<template>
    <div :class="{ 'active' : test }">{{test}}</div>
</template>
<script>
export default {
    data: {
        el: null,
    },

    computed: {
        test() {
            return this.el ? this.el.offsetTop : 0;
        }
    },

    mounted(){
        this.el = this.$el;
    }
}
</script>

As a side note, I don't believe you have access to the console in Vue.js computed properties, so I removed that bit.

like image 175
A Steinmetz Avatar answered Oct 01 '22 05:10

A Steinmetz


If a computed property is used in the template, its method will fire before the Vue instance is mounted, so this.$el will be undefined.

If your computed property is dependant on some property of this.$el, you can set it to a data property in the mounted hook (where this.$el will be defined).

In your case:

<template>
  <div :class="{ 'active' : test }"></div>
</template>

<script>
export default {
  data() {
    return { offsetTop: null };
  },
  computed: {
    test() {
      console.log(this.offsetTop);
    }
  },
  mounted() {
    this.offsetTop = this.$el.offsetTop;
  }
}
</script>
like image 29
thanksd Avatar answered Oct 01 '22 05:10

thanksd