Reputation: 1858
I need to get the height of an image/element, this is what I did:
mounted() {
this.infoHeight = this.$refs.info.clientHeight + 'px';
}
When I save then on hot reload it works, it gets the correct height but when I refresh the page it returns a smaller/wrong value. I also tried it on created()
and it's the same. On other situations it doesn't even return anything.
UPDATE (Temporary solution?)
mounted() {
setTimeout(() => this.infoHeight = this.$refs.info.clientHeight + 'px', 100);
}
I also tried using window.addEventListener('load', () => //todo)
but on some components it worked and on others it didn't.
Upvotes: 7
Views: 3995
Reputation: 115282
Try with $nextTick
which will execute after DOM update.
mounted() {
this.$nextTick(() => { this.infoHeight = this.$refs.info.clientHeight + 'px' });
}
Upvotes: 3
Reputation: 510
You can do this now in a way cleaner fashion using a ResizeObserver.
data: () => ({
infoHeight: 0,
resizeObserver: null
}),
mounted() {
this.resizeObserver = new ResizeObserver(this.onResize)
this.resizeObserver.observe(this.$refs.info)
this.onResize()
},
beforeUnmount() {
this.resizeObserver.unobserve(this.$refs.info)
},
methods: {
onResize() {
this.infoHeight = this.$refs.info.clientHeight + 'px'
}
}
Upvotes: 5
Reputation: 1
You could use this.$watch
with immediate:true
option :
mounted () {
this.$watch(
() => {
return this.$refs.info
},
(val) => {
this.infoHeight = this.$refs.info.clientHeight + 'px'
},
{
immediate:true,
deep:true
}
)
}
The above solution works only in the initial mount, the following one use MutationObserver
Vue.config.devtools = false;
Vue.config.productionTip = false;
new Vue({
el: '#app',
data: () => ({
infoHeight: 0,
observer: null,
img: "https://images.ctfassets.net/hrltx12pl8hq/6TOyJZTDnuutGpSMYcFlfZ/4dfab047c1d94bbefb0f9325c54e08a2/01-nature_668593321.jpg?fit=fill&w=480&h=270"
}),
mounted() {
const config = {
attributes: true,
childList: true,
subtree: true
};
this.observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation) {
this.infoHeight = this.$refs.info.clientHeight + 'px'
console.log(" changed ", this.$refs.info.clientHeight)
}
});
});
this.observer.observe(this.$refs.info, config);
},
methods: {
changeImg() {
this.img = "https://i.pinimg.com/originals/a7/3d/6e/a73d6e4ac85c6a822841e449b24c78e1.jpg"
},
}
})
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app" class="container">
<p>{{infoHeight}}</p>
<button class="btn btn-primary" @click="changeImg">Change image</button>
<div ref="info">
<img :src="img" alt="image" />
</div>
</div>
Upvotes: 1