当前位置:首页 > VUE

vue签名板实现

2026-01-19 16:49:45VUE

vue签名板实现

在Vue中实现签名板功能可以通过HTML5的Canvas API结合Vue的响应式特性完成。以下是具体实现方法:

基础实现步骤

安装依赖(如使用第三方库):

npm install vue-signature-pad  # 或使用原生Canvas

创建Vue组件(原生Canvas实现):

vue签名板实现

<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.initCanvas()
  },
  methods: {
    initCanvas() {
      this.canvas = this.$refs.canvas
      this.ctx = this.canvas.getContext('2d')
      this.resizeCanvas()
    },
    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)  // 可发送到服务器或下载
    },
    // 触摸事件处理
    handleTouchStart(e) {
      e.preventDefault()
      this.startDrawing(e)
    },
    handleTouchMove(e) {
      e.preventDefault()
      this.draw(e)
    },
    handleTouchEnd() {
      this.stopDrawing()
    }
  }
}
</script>

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

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

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

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

export default {
  components: {
    VueSignaturePad
  },
  methods: {
    undo() {
      this.$refs.signaturePad.undoSignature()
    },
    clear() {
      this.$refs.signaturePad.clearSignature()
    },
    save() {
      const { isEmpty, data } = this.$refs.signaturePad.saveSignature()
      if (!isEmpty) {
        console.log(data)  // 获取Base64格式签名
      }
    }
  }
}
</script>

功能扩展建议

  1. 响应式设计
    监听窗口变化时调用resizeCanvas()方法:

    window.addEventListener('resize', this.resizeCanvas)
  2. 保存为文件
    扩展saveSignature方法实现下载:

    vue签名板实现

    const link = document.createElement('a')
    link.download = 'signature.png'
    link.href = image
    link.click()
  3. 签名验证
    添加isEmpty检测防止空白提交:

    const isCanvasEmpty = () => {
      return !this.ctx.getImageData(0, 0, 
        this.canvas.width, this.canvas.height)
        .data.some(channel => channel !== 0)
    }
  4. 压力感应
    支持触控笔压力检测(需设备支持):

    this.ctx.lineWidth = e.pressure * 10

注意事项

  • 移动端需添加touch事件支持并调用e.preventDefault()
  • 高DPI屏幕需考虑像素比处理:
    const dpr = window.devicePixelRatio || 1
    this.canvas.width = this.canvas.offsetWidth * dpr
    this.canvas.height = this.canvas.offsetHeight * dpr
    this.ctx.scale(dpr, dpr)
  • 第三方库可能依赖signature_pad的特定版本,需检查兼容性

标签: vue
分享给朋友:

相关文章

vue点击实现排序

vue点击实现排序

实现点击排序的方法 在Vue中实现点击排序功能,可以通过以下几种方式完成: 使用计算属性结合排序方法 定义一个响应式数据存储排序状态,通过计算属性动态返回排序后的数组。点击事件切换排序状态。…

vue 页签实现

vue 页签实现

Vue 页签实现方法 在 Vue 中实现页签功能通常涉及动态组件、路由或状态管理。以下是几种常见的实现方式: 使用动态组件 通过 Vue 的 <component> 动态组件结合 v-f…

vue实现本地数据存储

vue实现本地数据存储

使用 localStorage 或 sessionStorage Vue 中可以直接调用浏览器提供的 localStorage 或 sessionStorage API 进行数据存储。localSto…

vue实现用户信息表

vue实现用户信息表

Vue 实现用户信息表的方法 使用 Vue CLI 创建项目 安装 Vue CLI 并初始化项目: npm install -g @vue/cli vue create user-info-tabl…

vue实现打印二维码

vue实现打印二维码

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

vue实现星星

vue实现星星

实现星星评分的Vue组件 使用Vue实现星星评分功能可以通过组件化方式完成,以下是一个完整的实现方案: 模板部分 <template> <div class="star-ra…