vuejs / vue

This is the repo for Vue 2. For Vue 3, go to https://github.com/vuejs/core
http://v2.vuejs.org
MIT License
208.04k stars 33.69k forks source link

Any way to tell when a component is done rendering? #2918

Closed coolcorey closed 8 years ago

coolcorey commented 8 years ago

I am attempting to use bootstrap-table. I can post more details, but the only way I can get it to work is to delay bootstrap-table from attaching/seeking the table until rendering by VueJS is complete. Is there any way to tell when the table component has finished it's first render?

At the moment, bootstrap-table works when I do a setTimeout for x (in this case 2000) milliseconds before returning the data.

phanan commented 8 years ago

Please ask these questions on the forum or Gitter.

FadyMak commented 8 years ago

Hi there! This question is best suited for the Forum or Gitter. To quickly answer your question, you can use the Lifecycle Hooks that Vue provides: http://vuejs.org/api/#Options-Lifecycle-Hooks

For your case, you can try using the ready hook depending on the specifics of bootstrap-table.

drasnop commented 7 years ago

In Vue 2.0, ready has been replaced by mounted. If you want to make sure that all child components have also been mounted, use vm.$nextTick:

mounted: function () {
  this.$nextTick(function () {
    // Code that will run only after the
    // entire view has been rendered
  })
}

Source: https://vuejs.org/v2/api/#Options-Lifecycle-Hooks

uthpalax commented 6 years ago

-@drasnop Wrong it does not guarantee that -> https://github.com/vuejs/vue-router/issues/289

matthewmorgan commented 6 years ago

@drasnop mounted => nextTick fires well before all children are rendered for me. :(

My use case is that I have a v-for rendering an array of objects from the Vuex store. Don't know if that matters, but FYI for anyone else seeing the same thing.

weituotian commented 6 years ago

does nextTick for all components updated?

piotrgulbis commented 6 years ago

@matthewmorgan i have the same thing, using a getter to load data from the store and then using a v-for in my template. Did you get your problem resolved?

blyszcz commented 6 years ago

@piotrgulbis @matthewmorgan @Uthpala @coolcorey I made a little 'work around' solution, a bit tricky, but it works, put this code into end of the function that ends your task for ex. fetchData() for example:

fetchData() {
  doSomeThing();
  setTimeout(() => { // setTimeout to put this into event queue
    // executed after render
  }, 0)
}

It pushes your callback into event queue, and finally, after execution stack is empty, and our view is rendered, our callback is called.

eddivalen commented 5 years ago

This is how I do it and it works for me: Before execute my action, I ask first if my component exists, until my target component is finally loaded.

 updated: function(){
    var ref = this
    this.$nextTick(function () {
      if(typeof ref.$refs.table != 'undefined'){
          ref.$refs.table.setPage(this.pageNum)
        }
      })
  }

My target component has a 'ref' prop, that one I used for the condition

<v-client-table ref="table">
orrd commented 5 years ago

Here is a solution from the comments of similar issue #9200:

https://www.npmjs.com/package/vue-force-next-tick

Apparently in some situations the "double requestAnimationFrame method" is needed.

manuelgeek commented 4 years ago

This is how I do it and it works for me: Before execute my action, I ask first if my component exists, until my target component is finally loaded.

 updated: function(){
    var ref = this
    this.$nextTick(function () {
      if(typeof ref.$refs.table != 'undefined'){
          ref.$refs.table.setPage(this.pageNum)
        }
      })
  }

My target component has a 'ref' prop, that one I used for the condition

<v-client-table ref="table">

works great