当前位置:首页 > VUE

vue签名板实现

2026-02-20 09:00:12VUE

实现 Vue 签名板的方法

使用 HTML5 Canvas 和 Vue 结合

在 Vue 中实现签名板可以通过 HTML5 的 Canvas 元素结合 Vue 的事件绑定和数据管理来完成。以下是一个基本的实现步骤。

安装依赖(可选)

如果需要更复杂的签名功能,可以安装专门的 Vue 签名库,例如 vue-signature-pad

npm install vue-signature-pad

基础实现代码

以下是一个不依赖第三方库的基础实现示例:

<template>
  <div>
    <canvas 
      ref="canvas"
      @mousedown="startDrawing"
      @mousemove="draw"
      @mouseup="stopDrawing"
      @mouseleave="stopDrawing"
      @touchstart="handleTouchStart"
      @touchmove="handleTouchMove"
      @touchend="handleTouchEnd"
    ></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.setCanvasSize();
    window.addEventListener('resize', this.setCanvasSize);
  },
  beforeDestroy() {
    window.removeEventListener('resize', this.setCanvasSize);
  },
  methods: {
    setCanvasSize() {
      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;
      this.ctx.lineWidth = 2;
      this.ctx.lineCap = 'round';
      this.ctx.strokeStyle = '#000';

      const rect = this.canvas.getBoundingClientRect();
      const x = e.clientX - rect.left;
      const y = e.clientY - rect.top;

      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 dataUrl = this.canvas.toDataURL('image/png');
      console.log(dataUrl); // 可以保存或上传到服务器
    },
    handleTouchStart(e) {
      e.preventDefault();
      const touch = e.touches[0];
      const mouseEvent = new MouseEvent('mousedown', {
        clientX: touch.clientX,
        clientY: touch.clientY
      });
      this.startDrawing(mouseEvent);
    },
    handleTouchMove(e) {
      e.preventDefault();
      const touch = e.touches[0];
      const mouseEvent = new MouseEvent('mousemove', {
        clientX: touch.clientX,
        clientY: touch.clientY
      });
      this.draw(mouseEvent);
    },
    handleTouchEnd(e) {
      e.preventDefault();
      const mouseEvent = new MouseEvent('mouseup', {});
      this.stopDrawing(mouseEvent);
    }
  }
};
</script>

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

使用第三方库(vue-signature-pad)

如果需要更完整的签名功能(如压力敏感度、平滑曲线等),可以使用 vue-signature-pad 库:

<template>
  <div>
    <VueSignaturePad 
      ref="signaturePad" 
      width="100%" 
      height="300px" 
      :options="{ penColor: '#000' }"
    />
    <button @click="clearSignature">清除</button>
    <button @click="saveSignature">保存</button>
  </div>
</template>

<script>
import VueSignaturePad from 'vue-signature-pad';

export default {
  components: {
    VueSignaturePad
  },
  methods: {
    clearSignature() {
      this.$refs.signaturePad.clearSignature();
    },
    saveSignature() {
      const { dataUrl } = this.$refs.signaturePad.saveSignature();
      console.log(dataUrl); // 可以保存或上传到服务器
    }
  }
};
</script>

注意事项

  • 响应式设计:确保 Canvas 的尺寸适配父容器,监听窗口变化并调整 Canvas 大小。
  • 触摸支持:移动端需要处理 touch 事件,转换为鼠标事件模拟绘制。
  • 保存格式toDataURL 支持多种格式(如 PNG、JPEG),可根据需求选择。
  • 性能优化:频繁绘制时注意避免不必要的重绘,使用 requestAnimationFrame 优化性能。

以上方法提供了从基础到进阶的 Vue 签名板实现方案,可根据项目需求选择适合的方式。

vue签名板实现

标签: vue
分享给朋友:

相关文章

vue实现滚动中断

vue实现滚动中断

Vue 实现滚动中断的方法 在 Vue 中实现滚动中断通常涉及监听滚动事件,并在特定条件下阻止默认行为或停止滚动。以下是几种常见方法: 监听滚动事件并阻止默认行为 通过 @scroll 或 @whe…

vue实现关键词轮播

vue实现关键词轮播

Vue 实现关键词轮播 基础实现方案 使用 Vue 的 v-for 和 setInterval 实现基础轮播效果: <template> <div class="keyword…

vue实现分屏

vue实现分屏

Vue 实现分屏的方法 分屏功能通常用于展示多个独立内容区域,以下是几种常见的实现方式: 使用 CSS Grid 布局 通过 CSS Grid 可以轻松创建分屏布局,在 Vue 组件中直接应用样式:…

vue实现跑车

vue实现跑车

Vue 实现跑车动画效果 使用 Vue 结合 CSS 动画可以实现跑车在屏幕上移动的效果。以下是一个完整的实现方案: 创建 Vue 组件结构 <template> <div…

vue实现切换

vue实现切换

Vue 实现切换功能的方法 在 Vue 中实现切换功能可以通过多种方式实现,以下是一些常见的方法: 使用 v-if 和 v-else 指令 通过条件渲染实现切换功能,适用于简单的显示/隐藏场景。…

vue 实现表单

vue 实现表单

Vue 表单实现方法 Vue.js 提供了多种方式实现表单,包括双向数据绑定、表单验证和动态表单生成。以下是常见的实现方法: 基础表单绑定 使用 v-model 指令实现表单元素与数据的双向绑定:…