vue 移动端实现签名
移动端签名功能实现(Vue)
核心思路:通过Canvas绘图实现签名,适配移动端触摸事件,支持导出图片。

依赖安装
使用vue-signature-pad库简化开发:

npm install vue-signature-pad
或原生Canvas实现(无需依赖):
<template>
<div class="signature-container">
<canvas
ref="canvas"
@touchstart="startDrawing"
@touchmove="draw"
@touchend="stopDrawing"
@mousedown="startDrawing"
@mousemove="draw"
@mouseup="stopDrawing">
</canvas>
<button @click="clearCanvas">清除</button>
<button @click="saveSignature">保存</button>
</div>
</template>
核心实现代码
export default {
data() {
return {
isDrawing: false,
canvas: null,
ctx: null
}
},
mounted() {
this.initCanvas()
},
methods: {
initCanvas() {
this.canvas = this.$refs.canvas
this.ctx = this.canvas.getContext('2d')
// 适配高清屏
const ratio = window.devicePixelRatio || 1
this.canvas.width = this.canvas.offsetWidth * ratio
this.canvas.height = this.canvas.offsetHeight * ratio
this.ctx.scale(ratio, ratio)
// 设置绘制样式
this.ctx.strokeStyle = '#000'
this.ctx.lineWidth = 2
this.ctx.lineCap = 'round'
},
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.touches ? e.touches[0].clientX : e.clientX) - rect.left,
y: (e.touches ? e.touches[0].clientY : e.clientY) - rect.top
}
},
clearCanvas() {
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height)
},
saveSignature() {
const image = this.canvas.toDataURL('image/png')
// 可通过API上传或本地保存
console.log(image)
}
}
}
样式优化
.signature-container {
position: relative;
width: 100%;
height: 300px;
}
canvas {
width: 100%;
height: 100%;
border: 1px solid #ddd;
background-color: #f9f9f9;
touch-action: none; /* 防止触摸滚动 */
}
button {
margin-top: 10px;
padding: 8px 15px;
}
移动端适配要点
- 防抖动处理:添加
touch-action: none防止页面滚动干扰 - 高清屏适配:通过
devicePixelRatio调整Canvas分辨率 - 双端事件:同时监听
touch和mouse事件 - 性能优化:复杂签名可考虑使用
requestAnimationFrame
进阶功能
- 压力感应:通过
touch.force(iOS)或event.pressure(Android)实现笔迹粗细变化 - 撤销功能:使用数组记录绘制路径实现多步撤销
- 背景图签名:在Canvas底层叠加背景图片
- 本地存储:使用
localStorage缓存签名数据
注意事项
- 部分安卓机型需要添加
meta标签禁用缩放:<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> - 横竖屏切换时需要重新计算Canvas尺寸
- 签名图片上传建议转为Blob格式减少传输体积






