vue手写签名如何实现
实现手写签名的基本思路
在Vue中实现手写签名功能通常需要借助HTML5的Canvas API,允许用户在画布上绘制签名,并支持保存为图片或Base64数据。以下是核心实现步骤。
创建Canvas画布组件
在Vue组件中嵌入Canvas元素,并设置初始样式:
<template>
<div>
<canvas
ref="signaturePad"
@mousedown="startDrawing"
@mousemove="draw"
@mouseup="stopDrawing"
@mouseleave="stopDrawing"
@touchstart="startDrawing"
@touchmove="draw"
@touchend="stopDrawing">
</canvas>
<button @click="clearCanvas">清除</button>
<button @click="saveSignature">保存</button>
</div>
</template>
初始化Canvas上下文
在mounted钩子中初始化画布并设置绘图上下文:
data() {
return {
isDrawing: false,
lastX: 0,
lastY: 0,
ctx: null
};
},
mounted() {
const canvas = this.$refs.signaturePad;
canvas.width = 500; // 设置画布宽度
canvas.height = 300; // 设置画布高度
this.ctx = canvas.getContext('2d');
this.ctx.strokeStyle = '#000000'; // 线条颜色
this.ctx.lineWidth = 2; // 线条粗细
}
实现绘图逻辑
添加绘图事件处理方法:
methods: {
startDrawing(e) {
this.isDrawing = true;
const { offsetX, offsetY } = this.getPosition(e);
this.lastX = offsetX;
this.lastY = offsetY;
},
draw(e) {
if (!this.isDrawing) return;
const { offsetX, offsetY } = this.getPosition(e);
this.ctx.beginPath();
this.ctx.moveTo(this.lastX, this.lastY);
this.ctx.lineTo(offsetX, offsetY);
this.ctx.stroke();
this.lastX = offsetX;
this.lastY = offsetY;
},
stopDrawing() {
this.isDrawing = false;
},
getPosition(e) {
const canvas = this.$refs.signaturePad;
if (e.type.includes('touch')) {
const rect = canvas.getBoundingClientRect();
return {
offsetX: e.touches[0].clientX - rect.left,
offsetY: e.touches[0].clientY - rect.top
};
}
return e;
}
}
添加清除和保存功能
实现清除画布和保存签名的功能:
methods: {
clearCanvas() {
this.ctx.clearRect(0, 0, this.$refs.signaturePad.width, this.$refs.signaturePad.height);
},
saveSignature() {
const dataUrl = this.$refs.signaturePad.toDataURL('image/png');
// 可通过emit事件传递数据,或直接下载
this.$emit('save', dataUrl);
}
}
优化绘图体验
为提升移动端体验,可添加以下CSS:
canvas {
border: 1px solid #ddd;
touch-action: none; /* 禁用默认触摸行为 */
}
使用第三方库简化实现
如需快速实现,可考虑使用现成库如vue-signature-pad:
npm install vue-signature-pad
使用示例:
import VueSignaturePad from 'vue-signature-pad';
export default {
components: { VueSignaturePad },
methods: {
save() {
const { dataUrl } = this.$refs.signaturePad.save();
console.log(dataUrl);
}
}
}
注意事项
- 跨设备兼容性需测试不同浏览器的触摸事件支持
- 高DPI屏幕需通过
window.devicePixelRatio调整画布分辨率 - 保存的图片格式建议使用PNG以保证透明背景
- 服务端保存时需处理Base64字符串的
data:image/png;base64,前缀







