当前位置:首页 > VUE

vue手写签名功能实现

2026-01-20 20:23:44VUE

实现 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>

移动端适配要点

  1. 确保添加 touch 事件支持
  2. 设置 viewport meta 标签:
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
  3. 防止触摸滚动:
    canvas {
    touch-action: none;
    }

保存签名数据

可以将签名保存为:

  • Base64 图片数据(直接使用 canvas.toDataURL())
  • 矢量路径数据(记录绘图坐标点)
  • 直接上传到服务器
// 获取PNG图片
const imageData = canvas.toDataURL('image/png');

// 获取矢量数据
const paths = []; // 在draw方法中记录坐标点

以上方法可根据项目需求选择或组合使用。

vue手写签名功能实现

标签: 功能vue
分享给朋友:

相关文章

vue实现tab标签

vue实现tab标签

Vue 实现 Tab 标签的方法 使用动态组件和 v-for 渲染标签 通过 v-for 循环生成标签页标题,结合 v-bind:class 动态切换激活状态。使用 v-show 或动态组件 <…

vue实现点击样式

vue实现点击样式

Vue 实现点击样式的方法 在 Vue 中实现点击样式可以通过多种方式完成,以下是几种常见的方法: 方法一:使用 v-bind:class 动态绑定类名 通过数据驱动的方式动态切换类名,结合…

前端多线程实现vue

前端多线程实现vue

前端多线程与Vue的结合 在Vue中实现多线程通常通过Web Worker技术完成。Web Worker允许在后台线程中运行脚本,避免阻塞主线程,适合处理计算密集型任务。 使用Web Worker的…

vue实现倍速播放功能

vue实现倍速播放功能

实现倍速播放功能 在Vue中实现倍速播放功能通常涉及HTML5的<video>元素或第三方播放器库(如video.js)。以下是两种常见的实现方式: 使用原生HTML5 video元素…

在线脑图 vue 实现

在线脑图 vue 实现

在线脑图 Vue 实现方案 使用开源库实现 推荐使用 mind-elixir 或 jsmind 这类开源库,它们专为脑图设计且支持 Vue 集成。 安装依赖: npm install mind…

vue优秀实现

vue优秀实现

Vue.js 优秀实现方法 响应式数据管理 使用 Vue 的 ref 和 reactive 处理基础类型和对象类型数据,结合 computed 计算属性优化渲染性能。对于复杂状态,推荐 Pinia 替…