vue实现手写签名
Vue 实现手写签名的方法
在 Vue 中实现手写签名功能可以通过 HTML5 的 Canvas 元素和 JavaScript 事件监听来完成。以下是具体实现步骤:
安装依赖(可选)
如果需要更高级的功能或简化开发,可以安装第三方库如 signature_pad:
npm install signature_pad
基础实现(使用原生 Canvas)
模板部分

<template>
<div>
<canvas
ref="signatureCanvas"
@mousedown="startDrawing"
@mousemove="draw"
@mouseup="stopDrawing"
@touchstart="startDrawing"
@touchmove="draw"
@touchend="stopDrawing"
></canvas>
<button @click="clearSignature">清除</button>
<button @click="saveSignature">保存</button>
</div>
</template>
脚本部分
<script>
export default {
data() {
return {
isDrawing: false,
canvas: null,
ctx: null
};
},
mounted() {
this.canvas = this.$refs.signatureCanvas;
this.ctx = this.canvas.getContext('2d');
this.resizeCanvas();
window.addEventListener('resize', this.resizeCanvas);
},
beforeDestroy() {
window.removeEventListener('resize', this.resizeCanvas);
},
methods: {
resizeCanvas() {
this.canvas.width = this.canvas.offsetWidth;
this.canvas.height = this.canvas.offsetHeight;
this.ctx.strokeStyle = '#000';
this.ctx.lineWidth = 2;
},
startDrawing(e) {
this.isDrawing = true;
const pos = this.getPosition(e);
this.ctx.beginPath();
this.ctx.moveTo(pos.x, pos.y);
},
draw(e) {
if (!this.isDrawing) return;
const pos = this.getPosition(e);
this.ctx.lineTo(pos.x, pos.y);
this.ctx.stroke();
},
stopDrawing() {
this.isDrawing = false;
},
getPosition(e) {
const rect = this.canvas.getBoundingClientRect();
return {
x: e.clientX - rect.left,
y: e.clientY - rect.top
};
},
clearSignature() {
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
},
saveSignature() {
const image = this.canvas.toDataURL('image/png');
console.log(image); // 可以保存或上传到服务器
}
}
};
</script>
样式部分

<style scoped>
canvas {
border: 1px solid #000;
width: 100%;
height: 300px;
background-color: #fff;
}
</style>
使用 signature_pad 库实现
模板部分
<template>
<div>
<canvas ref="signatureCanvas"></canvas>
<button @click="clear">清除</button>
<button @click="save">保存</button>
</div>
</template>
脚本部分
<script>
import SignaturePad from 'signature_pad';
export default {
data() {
return {
signaturePad: null
};
},
mounted() {
const canvas = this.$refs.signatureCanvas;
this.signaturePad = new SignaturePad(canvas);
this.resizeCanvas();
window.addEventListener('resize', this.resizeCanvas);
},
beforeDestroy() {
window.removeEventListener('resize', this.resizeCanvas);
},
methods: {
resizeCanvas() {
const canvas = this.$refs.signatureCanvas;
canvas.width = canvas.offsetWidth;
canvas.height = canvas.offsetHeight;
this.signaturePad.clear(); // 防止缩放时签名变形
},
clear() {
this.signaturePad.clear();
},
save() {
if (this.signaturePad.isEmpty()) {
alert('请先签名');
return;
}
const image = this.signaturePad.toDataURL('image/png');
console.log(image); // 可以保存或上传到服务器
}
}
};
</script>
移动端适配
- 添加
@touchstart、@touchmove和@touchend事件(已在基础实现中包含)。 - 禁用页面滚动防止签名时页面移动:
methods: { startDrawing(e) { e.preventDefault(); // 阻止默认行为 this.isDrawing = true; // 其他逻辑 } }
保存签名
签名可以转换为 Base64 或 Blob 格式上传到服务器:
// Base64 格式
const image = canvas.toDataURL('image/png');
// Blob 格式
canvas.toBlob((blob) => {
const formData = new FormData();
formData.append('signature', blob, 'signature.png');
// 上传逻辑
}, 'image/png');
注意事项
- Canvas 宽高:必须在代码中显式设置
canvas.width和canvas.height,否则绘制会模糊。 - 响应式设计:监听
resize事件并调整 Canvas 大小。 - 库的优势:
signature_pad提供了更平滑的绘制效果和内置方法(如isEmpty())。






