Vue中如何在div内部加载canvas 仅在loadModal为true时显示
问题根因
- 两个canvas使用了重复的
id属性:document.getElementById匹配元素时只会返回页面中第一个出现的对应id的元素,因此你始终拿到的是div外部的canvas,无法选中内部canvas。 - Vue的DOM更新是异步执行的:你刚将
loadModal设为true时,v-if控制的内部canvas还没完成挂载渲染,此时就算id不重复也无法拿到对应的DOM元素。
解决方案
步骤1:区分两个canvas的id
避免id重复冲突,给内部和外部的canvas设置不同的id,或者更推荐使用Vue的ref属性获取DOM,避免全局id污染。
步骤2:使用$nextTick等待DOM更新完成
修改逻辑代码,在loadModal赋值后,通过$nextTick的回调函数执行canvas绘制逻辑,确保此时内部canvas已经完成挂载。
修改后完整代码
视图代码
<div id="app"> <button @click="runModal()"> Click Me </button> <br><br> <div v-if="loadModal"> <canvas id="myCanvasInner" width="200" height="100" style="border:3px solid #d3d3d3; color:red;"> </canvas> </div> <canvas id="myCanvasOuter" width="200" height="100" style="border:1px solid #d3d3d3;"> </canvas> </div>
逻辑代码
new Vue({ el: "#app", data: { loadModal: false, }, methods: { runModal(){ this.loadModal = true; this.$nextTick(() => { // 获取内部canvas元素 const innerCanvas = document.getElementById("myCanvasInner"); const ctx = innerCanvas.getContext("2d"); ctx.beginPath(); ctx.arc(95, 50, 40, 0, 2 * Math.PI); ctx.stroke(); }) } } })
优化建议
更推荐使用Vue的ref特性获取DOM,不需要依赖全局id,写法更规范:
- 给内部canvas加ref属性:
<canvas ref="innerCanvas" ...> - 直接通过
this.$refs.innerCanvas获取元素,不需要调用document.getElementById。
内容的提问来源于stack exchange,提问作者Yahoo
相关产品推荐
相关产品推荐

