This article will demonstrate how to create a signature pad component in Vue 3 in a few simple steps.
Step 1. Install dependencies
npm i signature_pad npm i @vueuse/core
Step 2. Create a component
<!-- template --> <div ref="wrapperRef" class="wrapper"> <canvas ref="canvasRef" class="canvas"></canvas> <div class="label">Signature</div> </div>
// style .wrapper { position: relative; width: 350px; height: 150px; border-radius: 4px; border: 1px solid rgba(0, 0, 0, 0.24); } .canvas { cursor: crosshair; } .label { position: absolute; top: 10px; left: 12px; font-size: 12px; color: rgba(0, 0, 0, 0.6) }
Step 3. Ensure that the canvas is always the same size as the wrapper
<!-- template --> <canvas ref="canvasRef" class="canvas" :width="width" :height="height"></canvas> // script import { useElementSize } from '@vueuse/core'; const wrapperRef = ref(); const { width, height } = useElementSize(wrapperRef);
Step 4. Initialize signaturePad and configure emits
import SignaturePad from 'signature_pad'; const emit = defineEmits(['saveSignature']); const canvasRef = ref(); const signaturePad = ref(); const saveSignature = () => { emit('saveSignature', signaturePad.value.toDataURL()); }; onMounted(() => { signaturePad.value = new SignaturePad(canvasRef.value); signaturePad.value.addEventListener('endStroke', saveSignature); }); onUnmounted(() => { signaturePad.value.removeEventListener('endStroke', saveSignature); });
Step 5. Prevent the canvas from being cleared when its size changes
watch([width, height], async () => { await nextTick(); signaturePad.value.fromData(signaturePad.value.toData()); });
Result
