I'm trying to make my canvas fit its container, in a vue component. I fire resizeCanvas() in mounted, but the container height and width are 0. How can I have a canvas that fits its container, so that I can change the container size using css and it will update the canvas ? (Sorry for my english, i'm not fluent)
<template lang="html">
<div class="container" ref="container">
<canvas ref="canvas" :width="width" :height="height"></canvas>
</div>
</template>
<script>
export default {
name: "monster",
data ()
{
return {
width: 512,
height: 512
}
}
methods: {
resizeCanvas(){
console.log(this.$refs.container.offsetWidth); // logs 0
this.width = this.$refs.container.offsetWidth
this.height = this.$refs.container.offsetWidth
}
},
mounted ()
{
console.log(this.$refs.container.offsetWidth) // logs 0
window.addEventListener("resize", this.resizeCanvas);
this.resizeCanvas()
},
unmounted() {
window.removeEventListener("resize", this.resizeCanvas);
},
}
</script>
<style lang="css" scoped>
.container {
width: 100%; height: 100%
}
</style>
CodePudding user response:
The mounted lifecycle hook in VueJS does not guarantee that the DOM is ready: you will need to wait for this.$nextTick()
and then check the dimensions of your container element.
You can do it by moving the logic into the callback of nextTick, i.e.:
mounted () {
this.$nextTick(() => {
console.log(this.$refs.container.offsetWidth);
window.addEventListener("resize", this.resizeCanvas);
this.resizeCanvas();
});
},
If you're familiar with the async/await way of doing things, then you can also do this:
async mounted () {
await this.$nextTick();
console.log(this.$refs.container.offsetWidth);
window.addEventListener("resize", this.resizeCanvas);
this.resizeCanvas();
},
Another possibility is to delegate this "wait for DOM to be ready" responsibility to the resizeCanvas
function, so you have full abstraction and separation of concerns:
methods: {
async resizeCanvas(){
await this.$nextTick();
this.width = this.$refs.container.offsetWidth
this.height = this.$refs.container.offsetWidth
}
},
mounted () {
window.addEventListener("resize", this.resizeCanvas);
this.resizeCanvas();
},