vue手写签名功能实现
实现 Vue 手写签名功能
在 Vue 中实现手写签名功能通常需要结合 HTML5 的 Canvas 和触摸/鼠标事件。以下是具体实现步骤:
安装依赖(可选)
如果需要快速实现,可以使用现成的签名库:
npm install vue-signature-pad
原生 Canvas 实现
对于自定义需求,可以直接用 Canvas 实现:
<template>
<div>
<canvas
ref="canvas"
@mousedown="startDrawing"
@mousemove="draw"
@mouseup="stopDrawing"
@touchstart="startDrawing"
@touchmove="draw"
@touchend="stopDrawing">
</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.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;
},
startDrawing(e) {
this.isDrawing = true;
this.draw(e);
},
draw(e) {
if (!this.isDrawing) return;
const rect = this.canvas.getBoundingClientRect();
const x = (e.clientX || e.touches[0].clientX) - rect.left;
const y = (e.clientY || e.touches[0].clientY) - rect.top;
this.ctx.lineWidth = 2;
this.ctx.lineCap = 'round';
this.ctx.lineJoin = 'round';
this.ctx.strokeStyle = '#000';
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 image = this.canvas.toDataURL('image/png');
console.log(image); // 可以发送到服务器或保存
}
}
}
</script>
<style>
canvas {
border: 1px solid #000;
width: 100%;
height: 300px;
background-color: white;
}
</style>
使用 vue-signature-pad 库
对于更简单的实现:
<template>
<div>
<VueSignaturePad
ref="signaturePad"
width="100%"
height="300px"
:options="{ penColor: '#000' }"
/>
<button @click="clear">清除</button>
<button @click="save">保存</button>
</div>
</template>
<script>
import VueSignaturePad from 'vue-signature-pad';
export default {
components: { VueSignaturePad },
methods: {
clear() {
this.$refs.signaturePad.clearSignature();
},
save() {
const { isEmpty, data } = this.$refs.signaturePad.saveSignature();
if (!isEmpty) {
console.log(data); // 可以发送到服务器
}
}
}
}
</script>
移动端适配要点
- 确保添加 touch 事件支持
- 设置 viewport meta 标签:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> - 防止触摸滚动:
canvas { touch-action: none; }
保存签名数据
可以将签名保存为:
- Base64 图片数据(直接使用 canvas.toDataURL())
- 矢量路径数据(记录绘图坐标点)
- 直接上传到服务器
// 获取PNG图片
const imageData = canvas.toDataURL('image/png');
// 获取矢量数据
const paths = []; // 在draw方法中记录坐标点
以上方法可根据项目需求选择或组合使用。







