响应式 canvas vuejs

Responsive canvas vuejs

我试图让我的 canvas 适合它的容器,在 vue 组件中。 我在安装时触发 resizeCanvas(),但容器高度和宽度为 0。 我怎样才能拥有适合其容器的 canvas ,以便我可以使用 css 更改容器大小并更新 canvas ? (对不起我的英语,我不流利)

<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>

VueJS 中的挂载生命周期挂钩不保证 DOM 已准备就绪:您需要等待 this.$nextTick() 然后检查容器元素的尺寸。

您可以通过将逻辑移动到 nextTick 的回调中来实现,即:

mounted () {
    this.$nextTick(() => {
        console.log(this.$refs.container.offsetWidth);
        window.addEventListener("resize", this.resizeCanvas);
        this.resizeCanvas();
    });
},

如果您熟悉 async/await 做事方式,那么您也可以这样做:

async mounted () {
    await this.$nextTick();

    console.log(this.$refs.container.offsetWidth);
    window.addEventListener("resize", this.resizeCanvas);
    this.resizeCanvas();
},

另一种可能性是将“等待 DOM 准备就绪”的责任委托给 resizeCanvas 函数,这样您就可以完全抽象和分离关注点:

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();
},