vue.js 通过响应式数据驱动 canvas 重绘,核心是用 ref 获取 canvas、watch 监听数据变化并调用 draw() 函数;推荐将图形状态建模为响应式数组(如 shapes),结合防抖、离屏渲染等优化性能,并可封装为 usecanvas hook 复用。

Vue.js 本身不直接监听 Canvas 元素的绘图状态,但可以通过响应式数据驱动 Canvas 的重绘逻辑——关键在于把画布的渲染逻辑封装成受 Vue 响应式系统控制的“副作用”,让数据变化自动触发 ctx.clearRect() 和 ctx.drawImage() 等操作。
用 ref + watch 主动触发 Canvas 重绘
Canvas 渲染是命令式操作,不能像 DOM 那样靠模板自动更新。最常用的方式是:用 ref 获取 canvas 元素,用 watch 监听响应式数据(如坐标、颜色、形状列表),数据一变就手动调用绘制函数。
- 在 setup 中用
const canvas = ref(null)绑定 DOM 元素 - 用
onMounted初始化 2D 上下文:const ctx = canvas.value.getContext('2d') - 定义一个
draw()函数,里面写清空+重绘逻辑 - 对需要响应的数据(比如
position、isDrawing)用watch包裹,调用draw()
把 Canvas 状态抽象为可响应式的数据模型
避免在 watch 里写大量绘图代码,推荐把图形状态建模为响应式对象或数组。例如:
- 定义
const shapes = ref([{ type: 'circle', x: 100, y: 100, r: 20 }]) - 绘制函数遍历
shapes.value,按类型分别调用ctx.arc()或ctx.fillRect() - 添加新图形时只需
shapes.value.push(...),watch 自动触发重绘 - 支持撤销/重做?只需替换
shapes.value数组即可
性能优化:避免无意义的重绘
Canvas 每次重绘都要清空再画,频繁触发会卡顿。需谨慎控制 watch 的粒度和时机:
- 用
{ deep: false }避免监听嵌套对象深层变化(除非真需要) - 对连续拖动类操作,用
debounce或requestAnimationFrame节流 - 只重绘变化区域?可用
ctx.save()/ctx.clip()局部刷新,但多数场景全画布重绘更简单可靠 - 静态背景+动态前景分离?把不变部分画到离屏 canvas,主 canvas 只画变化元素
结合 Composition API 封装可复用的 Canvas Hook
把 canvas 初始化、上下文获取、重绘调度抽成自定义 Hook,提升复用性:
- 创建
useCanvas(canvasRef, drawFn, dependencies) - 内部自动处理 mounted、watch、清理逻辑
- 外部只需传入数据依赖项(如
[x, y, color]),无需重复写 watch - 支持传入 shouldUpdate 判断函数,跳过某些无效更新
不复杂但容易忽略:Canvas 是位图,没有“虚拟节点”概念,所有响应式都得靠开发者显式连接数据与绘图行为。只要守住“数据变 → 触发 draw()”这一条主线,就能稳稳实现响应式 Canvas 渲染。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











