当前位置:首页 > VUE

vue 实现电子签名

2026-02-19 13:43:07VUE

实现电子签名的基础方法

使用Vue实现电子签名功能,可以通过HTML5的Canvas元素结合触摸或鼠标事件完成。核心步骤包括初始化画布、监听绘制事件、保存签名数据。

<template>
  <div>
    <canvas 
      ref="signaturePad" 
      @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.signaturePad;
    this.ctx = this.canvas.getContext('2d');
    this.resizeCanvas();
    window.addEventListener('resize', this.resizeCanvas);
  },
  methods: {
    resizeCanvas() {
      this.canvas.width = this.canvas.offsetWidth;
      this.canvas.height = this.canvas.offsetHeight;
    },
    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 || e.touches[0].clientX) - rect.left,
        y: (e.clientY || e.touches[0].clientY) - rect.top
      };
    },
    clearSignature() {
      this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
    },
    saveSignature() {
      const dataURL = this.canvas.toDataURL('image/png');
      console.log(dataURL); // 可上传至服务器或本地保存
    }
  }
};
</script>

<style scoped>
canvas {
  border: 1px solid #000;
  width: 100%;
  height: 300px;
  background-color: #f8f8f8;
}
</style>

使用第三方库优化体验

对于更专业的签名处理,可使用现成库如signature_pad

  1. 安装依赖:

    vue 实现电子签名

    npm install signature_pad
  2. 组件实现:

    
    <template>
    <div>
     <canvas ref="signatureCanvas"></canvas>
     <button @click="clear">清除</button>
     <button @click="save">保存</button>
    </div>
    </template>
import SignaturePad from 'signature_pad';

export default { data() { return { signaturePad: null }; }, mounted() { const canvas = this.$refs.signatureCanvas; canvas.width = canvas.offsetWidth; canvas.height = canvas.offsetHeight; this.signaturePad = new SignaturePad(canvas); }, methods: { clear() { this.signaturePad.clear(); }, save() { if (this.signaturePad.isEmpty()) { alert('请先签名'); return; } const data = this.signaturePad.toDataURL(); console.log(data); } } };

vue 实现电子签名

```

移动端适配要点

  1. 防止触摸滚动:在画布上添加@touchmove.prevent修饰符
  2. 笔迹平滑:调整signature_padthrottleminWidth参数
  3. 响应式设计:监听窗口变化自动调整画布尺寸
mounted() {
  this.initSignaturePad();
  window.addEventListener('resize', this.handleResize);
},
methods: {
  initSignaturePad() {
    const canvas = this.$refs.signatureCanvas;
    this.signaturePad = new SignaturePad(canvas, {
      minWidth: 1,
      maxWidth: 3,
      throttle: 16
    });
    this.handleResize();
  },
  handleResize() {
    const canvas = this.$refs.signatureCanvas;
    canvas.width = canvas.offsetWidth;
    canvas.height = canvas.offsetHeight;
    this.signaturePad.clear(); // 防止缩放导致笔迹变形
  }
}

签名数据后端处理

保存的Base64数据可通过以下方式处理:

  1. 前端转换:将Base64转为Blob对象上传

    function dataURLToBlob(dataURL) {
    const arr = dataURL.split(',');
    const mime = arr[0].match(/:(.*?);/)[1];
    const bstr = atob(arr[1]);
    let n = bstr.length;
    const u8arr = new Uint8Array(n);
    while (n--) {
     u8arr[n] = bstr.charCodeAt(n);
    }
    return new Blob([u8arr], { type: mime });
    }
  2. 后端验证:检查签名图片的有效性(非空白)

    isEmpty() {
    return this.signaturePad.isEmpty();
    }

高级功能扩展

  1. 笔迹颜色设置:通过penColor参数调整
  2. 背景网格:在Canvas底层绘制辅助线
  3. 压力感应:支持数位板压感(需浏览器支持)
  4. 时间戳水印:在保存时添加签名时间信息
// 设置笔迹颜色示例
setPenColor(color) {
  this.signaturePad.penColor = color;
}

以上方案可根据实际需求组合使用,纯前端实现适合简单场景,结合后端存储则能实现完整电子签名流程。

标签: 电子签名vue
分享给朋友:

相关文章

vue实现菜单栏锚点

vue实现菜单栏锚点

实现锚点菜单的基本思路 在Vue中实现菜单栏锚点功能,主要涉及两个方面:创建可跳转的锚点位置,以及菜单项的点击滚动控制。通过监听滚动事件可以高亮当前可见区域的对应菜单项。 创建页面锚点位置 在需要跳…

vue实现打印二维码

vue实现打印二维码

安装二维码生成库 使用 qrcode 或 vue-qrcode 库生成二维码。通过 npm 安装: npm install qrcode vue-qrcode 生成二维码 在 Vue 组件中引…

vue实现autocomplete

vue实现autocomplete

Vue 实现 Autocomplete 功能 Vue 中实现 Autocomplete(自动完成)功能可以通过自定义组件或使用现有库完成。以下是几种常见方法: 方法一:使用 Vue 原生实现 创建…

vue实现递归

vue实现递归

Vue 实现递归组件的方法 在 Vue 中实现递归组件通常用于处理树形结构数据(如菜单、评论列表、文件目录等)。以下是具体实现方法: 定义递归组件 通过 name 选项让组件可以递归调用自身:…

vue实现frame

vue实现frame

Vue 中实现 iframe 的方法 在 Vue 中可以通过直接使用 <iframe> 标签或动态绑定 src 属性来实现 iframe 功能。 基本用法 <template…

vue实现试卷

vue实现试卷

Vue实现试卷系统的基本思路 使用Vue.js构建试卷系统需要结合组件化开发、状态管理和后端数据交互。核心功能包括题目展示、答题逻辑、计时器和提交答案。 核心功能模块划分 试卷组件结构 试卷容器组…