Reputation: 3335
I'm aware of mounted
and created
being life cycle hooks and have tried them. I've also tried using $nextTick
within mounted and that does not work to get an accurate render either. I am currently trying to access some data out of a dom node after the initial render. Here's the pertinent part of my code:
mounted() {
console.log(this.$el.getBoundingClientRect().top);
},
This is giving me incorrect data. However, using this code:
mounted() {
setTimeout(() => {
console.log(this.$el.getBoundingClientRect().top);
}, 1000)
},
Does net me the correct data. The threshold is about ~700-900 ms before I start getting the correct data.
Why is the lifecycle invoke when everything hasn't fully rendered?
Does it have to do with sibling components that haven't quite mounted yet that might be pushing dimensions?
Is there a solution, an event that I can hook into that basically says, 'everything on the page has rendered'.
I don't love the setTimeout
solution that I came up with for obvious reasons.
Upvotes: 4
Views: 3126
Reputation: 43881
Due to the fact that things render asynchronously, you may not be able to be sure that the position isn't going to change. You will likely need to get the position every time something updates. You can do that with a custom directive, whose update
function will be called when things update.
Here's a little demo:
new Vue({
el: '#app',
data: {
ht: 100,
top: null
},
directives: {
bounding(el, binding, vnode) {
vnode.context[binding.expression] = el.getBoundingClientRect().top;
}
},
mounted() {
let times = 5;
const i = setInterval(() => {
this.ht += 10;
if (--times < 1) {
clearInterval(i);
}
}, 1000);
}
});
<script src="//unpkg.com/vue@latest/dist/vue.js"></script>
<div id="app">
<div :style="{height: `${ht}px`}">Hi</div>
<div v-bounding="top">{{top}}</div>
</div>
Upvotes: 1
Reputation: 221
Q1: The lifecycle hooks are only concerned about the instance itself and not the rest of the dom. Hence - the rest of the page can be pending while the component is fully mounted.
Q2: Same as Q1.
Q3: You could use this:
document.addEventListener("DOMContentLoaded", function(event) {
console.log(this.$el.getBoundingClientRect().top);
});
For an more indepth answer: $(document).ready equivalent without jQuery
Edit
You should use this instead:
window.addEventListener("load", function(event) {
console.log(this.$el.getBoundingClientRect().top);
});
I forgot about the external resources.
DOMContentLoaded
is fired when the dom is loaded ie. html. load
is fired after the external resources have been loaded. Further reading: https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onload
Upvotes: 1