user3356802
user3356802

Reputation: 158

How do I access dynamic elements in Vue.js?

I am creating some divs using v-for:

<div class="foo" v-for="bar in bars">{{bar.text}}</div>

The data for the divs comes from an Axios request:

created() {
  axios('get/data').then( response => {
    this.bars = response.data;
  });
}

This all works fine and renders properly.

However, once they're created, I want to access the divs to find out things like getBoundingClientRect, and this is where I get stuck.

I don't understand why this.$el.querySelectorAll('.foo') doesn't work when this.$el clearly has all the .foo divs in it. I assume it's something to do with the DOM not yet having been updated, but I don't understand how one bit works while the other doesn't.

mounted() {
  console.log(this.$el); //Outputs all the .foo divs
  console.log(this.$el.querySelectorAll('.foo')); //Outputs empty array
}

Using this.$el.querySelectorAll('.foo') in updated() works fine, but I only need to run the code once, not on every update.

Vue version is 2.6.10

Upvotes: 1

Views: 2047

Answers (2)

Aziz.G
Aziz.G

Reputation: 3721

With vuejs better using $ref

$Ref Documentation

<div ref="myElement"/>

mounted(){
  const { myElement} = this.$refs;
  console.log(myElement)
}

then you have more control on your element

Upvotes: 0

Daniel
Daniel

Reputation: 35724

you can use $nextTick after the data was loaded, which should show the div tags

created() {
  axios('get/data')
  .then( response => {
    this.bars = response.data;

    this.$nextTick(() => {
        console.log(this.$el.querySelectorAll('.foo')); 
    });
  });
}

As to why you're getting the seemingly strange behaviour, my theory is this...

this.$el logs an object that keeps updating even after the instance gets mounted. The this.$el.querySelectorAll however returns a snapshot at the time.

That said, using this.$el.querySelectorAll should be avoided when possible in lieu of $refs. However you will see the same issue, and if you have dynamically generated repeating content (like when using v-for) and/or if you're interfacing it with another library, querySelectorAll may be a better option.

Upvotes: 1

Related Questions