vue签名板实现
实现 Vue 签名板的方法
使用 HTML5 Canvas 和 Vue 结合
在 Vue 中实现签名板可以通过 HTML5 的 Canvas 元素结合 Vue 的事件绑定和数据管理来完成。以下是一个基本的实现步骤。
安装依赖(可选)
如果需要更复杂的签名功能,可以安装专门的 Vue 签名库,例如 vue-signature-pad:
npm install vue-signature-pad
基础实现代码
以下是一个不依赖第三方库的基础实现示例:
<template>
<div>
<canvas
ref="canvas"
@mousedown="startDrawing"
@mousemove="draw"
@mouseup="stopDrawing"
@mouseleave="stopDrawing"
@touchstart="handleTouchStart"
@touchmove="handleTouchMove"
@touchend="handleTouchEnd"
></canvas>
<button @click="clearCanvas">清除</button>
<button @click="saveSignature">保存</button>
</div>
</template>
<script>
export default {
data() {
return {
isDrawing: false,
canvas: null,
ctx: null,
};
},
mounted() {
this.canvas = this.$refs.canvas;
this.ctx = this.canvas.getContext('2d');
this.setCanvasSize();
window.addEventListener('resize', this.setCanvasSize);
},
beforeDestroy() {
window.removeEventListener('resize', this.setCanvasSize);
},
methods: {
setCanvasSize() {
this.canvas.width = this.canvas.offsetWidth;
this.canvas.height = this.canvas.offsetHeight;
},
startDrawing(e) {
this.isDrawing = true;
this.draw(e);
},
draw(e) {
if (!this.isDrawing) return;
this.ctx.lineWidth = 2;
this.ctx.lineCap = 'round';
this.ctx.strokeStyle = '#000';
const rect = this.canvas.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
this.ctx.lineTo(x, y);
this.ctx.stroke();
this.ctx.beginPath();
this.ctx.moveTo(x, y);
},
stopDrawing() {
this.isDrawing = false;
this.ctx.beginPath();
},
clearCanvas() {
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
},
saveSignature() {
const dataUrl = this.canvas.toDataURL('image/png');
console.log(dataUrl); // 可以保存或上传到服务器
},
handleTouchStart(e) {
e.preventDefault();
const touch = e.touches[0];
const mouseEvent = new MouseEvent('mousedown', {
clientX: touch.clientX,
clientY: touch.clientY
});
this.startDrawing(mouseEvent);
},
handleTouchMove(e) {
e.preventDefault();
const touch = e.touches[0];
const mouseEvent = new MouseEvent('mousemove', {
clientX: touch.clientX,
clientY: touch.clientY
});
this.draw(mouseEvent);
},
handleTouchEnd(e) {
e.preventDefault();
const mouseEvent = new MouseEvent('mouseup', {});
this.stopDrawing(mouseEvent);
}
}
};
</script>
<style>
canvas {
border: 1px solid #000;
width: 100%;
height: 300px;
background-color: #fff;
}
</style>
使用第三方库(vue-signature-pad)
如果需要更完整的签名功能(如压力敏感度、平滑曲线等),可以使用 vue-signature-pad 库:
<template>
<div>
<VueSignaturePad
ref="signaturePad"
width="100%"
height="300px"
:options="{ penColor: '#000' }"
/>
<button @click="clearSignature">清除</button>
<button @click="saveSignature">保存</button>
</div>
</template>
<script>
import VueSignaturePad from 'vue-signature-pad';
export default {
components: {
VueSignaturePad
},
methods: {
clearSignature() {
this.$refs.signaturePad.clearSignature();
},
saveSignature() {
const { dataUrl } = this.$refs.signaturePad.saveSignature();
console.log(dataUrl); // 可以保存或上传到服务器
}
}
};
</script>
注意事项
- 响应式设计:确保 Canvas 的尺寸适配父容器,监听窗口变化并调整 Canvas 大小。
- 触摸支持:移动端需要处理
touch事件,转换为鼠标事件模拟绘制。 - 保存格式:
toDataURL支持多种格式(如 PNG、JPEG),可根据需求选择。 - 性能优化:频繁绘制时注意避免不必要的重绘,使用
requestAnimationFrame优化性能。
以上方法提供了从基础到进阶的 Vue 签名板实现方案,可根据项目需求选择适合的方式。







