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
