Vue实现画布
Vue 实现画布的方法
使用 HTML5 Canvas 标签
在 Vue 组件中直接使用 HTML5 的 <canvas> 标签创建画布。通过 ref 获取 DOM 元素,并在 mounted 生命周期中初始化画布上下文。
<template>
<canvas ref="canvas" width="400" height="300"></canvas>
</template>
<script>
export default {
mounted() {
const canvas = this.$refs.canvas;
const ctx = canvas.getContext('2d');
ctx.fillStyle = 'red';
ctx.fillRect(10, 10, 100, 100);
}
}
</script>
动态绑定画布属性
通过 Vue 的响应式特性动态绑定画布的宽度、高度或其他属性。例如,根据数据变化调整画布尺寸。

<template>
<canvas
ref="canvas"
:width="canvasWidth"
:height="canvasHeight"
></canvas>
</template>
<script>
export default {
data() {
return {
canvasWidth: 400,
canvasHeight: 300
};
},
mounted() {
this.drawCanvas();
},
methods: {
drawCanvas() {
const ctx = this.$refs.canvas.getContext('2d');
ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
ctx.fillStyle = 'blue';
ctx.fillRect(20, 20, 150, 100);
}
}
}
</script>
封装画布组件
将画布逻辑封装为可复用的 Vue 组件,通过 props 接收外部参数(如初始绘图指令)。
<!-- CanvasComponent.vue -->
<template>
<canvas ref="canvas" :width="width" :height="height"></canvas>
</template>
<script>
export default {
props: {
width: { type: Number, default: 400 },
height: { type: Number, default: 300 },
drawCommands: { type: Array, default: () => [] }
},
mounted() {
this.renderCanvas();
},
methods: {
renderCanvas() {
const ctx = this.$refs.canvas.getContext('2d');
this.drawCommands.forEach(cmd => {
if (cmd.type === 'rect') {
ctx.fillStyle = cmd.color;
ctx.fillRect(cmd.x, cmd.y, cmd.w, cmd.h);
}
});
}
}
}
</script>
处理用户交互
监听画布上的鼠标事件(如点击、拖拽)实现交互式绘图。结合 Vue 的事件机制传递数据。

<template>
<canvas
ref="canvas"
@mousedown="startDrawing"
@mousemove="draw"
@mouseup="stopDrawing"
></canvas>
</template>
<script>
export default {
data() {
return {
isDrawing: false,
lastX: 0,
lastY: 0
};
},
methods: {
startDrawing(e) {
this.isDrawing = true;
[this.lastX, this.lastY] = [e.offsetX, e.offsetY];
},
draw(e) {
if (!this.isDrawing) return;
const ctx = this.$refs.canvas.getContext('2d');
ctx.beginPath();
ctx.moveTo(this.lastX, this.lastY);
ctx.lineTo(e.offsetX, e.offsetY);
ctx.stroke();
[this.lastX, this.lastY] = [e.offsetX, e.offsetY];
},
stopDrawing() {
this.isDrawing = false;
}
}
}
</script>
使用第三方库
集成第三方绘图库(如 Fabric.js、Konva.js)实现高级功能(如对象层级、事件系统)。以 Fabric.js 为例:
<template>
<canvas ref="canvas"></canvas>
</template>
<script>
import { fabric } from 'fabric';
export default {
mounted() {
const canvas = new fabric.Canvas(this.$refs.canvas, {
width: 500,
height: 400
});
const rect = new fabric.Rect({
left: 100,
top: 100,
width: 60,
height: 70,
fill: 'green'
});
canvas.add(rect);
}
}
</script>
响应式画布清理
在数据变化时清理并重绘画布,结合 watch 监听数据变化。
<script>
export default {
props: ['items'],
watch: {
items: {
handler() {
this.redraw();
},
deep: true
}
},
methods: {
redraw() {
const ctx = this.$refs.canvas.getContext('2d');
ctx.clearRect(0, 0, this.width, this.height);
this.items.forEach(item => {
ctx.fillStyle = item.color;
ctx.fillRect(item.x, item.y, item.w, item.h);
});
}
}
}
</script>
注意事项
- 性能优化:频繁绘制的场景建议使用
requestAnimationFrame控制渲染节奏。 - 跨组件通信:复杂绘图逻辑可通过 Vuex 或事件总线管理状态。
- 高清屏适配:通过
window.devicePixelRatio缩放画布解决 Retina 屏模糊问题。 - 销毁处理:使用第三方库时,在
beforeDestroy生命周期中手动释放资源。





