如何使用 v-if 绘制 Canvas 条件加载?

How can I draw Canvas conditional onload with v-if?

我是 Vue 和 JavaScript 的新手,所以请帮助我理解这个问题:

我想在页面上动态显示不同的 canvas 元素。 canvas 的绘图在单独的 script.js 文件中定义。

这是我的代码的一部分:

<canvas v-if="checkedBoxes.includes('Heart')" onload="drawHeart();" id="heartCanvas" width="300" height="240"></canvas>
<canvas v-if="checkedBoxes.includes('Star')" onload="drawStar();" id="starCanvas" width="240" height="240"></canvas>

script.js:

function drawHeart() {
let heartCanvas = document.getElementById("heartCanvas");
let c = heartCanvas.getContext('2d');
c.beginPath();
... }

但是,当出现canvas元素时,Javascript函数drawXY()不会绘制它。在我看来,当元素出现在页面上时,不会触发 onload 事件。我也用Vue表达式v-on:load="drawXY"试过了,没有成功。当我将事件触发器更改为 onclick 时,它起作用了,但这不是我需要的。

所以我终于找到了解决问题的方法!

据我所知,并非每个 HTML 元素都支持 onload 事件,只有少数元素如 <body>, <frame>, <iframe>, <img> ,... 参见

所以我在 canvas 元素之后添加了一个空图像,它在加载图像时执行 drawXY() 函数。

这是更新后的代码:

<template v-if="checkedBoxes.includes('Heart')">
    <canvas id="heartCanvas" width="300" height="240"></canvas>
    <!-- empty image for onload event -->
    <img onload="drawHeart();" src="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=" width="0" height="0" alt="" />
</template>

<template v-if="checkedBoxes.includes('Star')">
    <canvas id="starCanvas" width="240" height="240"></canvas>
    <!-- empty image for onload event -->
    <img onload="drawStar();" src="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=" width="0" height="0" alt="" />
</template>

这是我发现的最好的解决方法,因为其他变体(例如在选中复选框后立即执行函数)通常最终无法正常工作,因为 <canvas> 元素尚未呈现,因此, document.getElementById returns 空。 <script> v-if 模板中不允许使用标签,因为它们可能会产生严重的副作用。

不过如果你有更好的解决方案,欢迎分享!