# How to Listen to on-change and on-complete Events in vue3-otp-input

> Learn how to listen to on-change and on-complete events in vue3-otp-input. Capture real-time OTP input changes and completion states effortlessly.

- Repository: [Ejiro Asiuwhu/vue3-otp-input](https://github.com/ejirocodes/vue3-otp-input)
- Tags: how-to-guide
- Published: 2026-03-01

---

**To capture real-time OTP input changes and completion states in vue3-otp-input, bind the `@on-change` and `@on-complete` event listeners to the component; these events emit the current OTP string value after every keystroke and when the input length matches the `numInputs` prop.**

The `vue3-otp-input` library by ejirocodes provides a Vue 3 composition-API-based component for one-time password entry. Understanding how to listen to its `on-change` and `on-complete` events is essential for implementing real-time validation, auto-submission, and user feedback mechanisms.

## Event Architecture in vue3-otp-input

The component defines three custom events using Vue 3's `defineEmits` macro in [`src/components/vue3-otp-input.vue`](https://github.com/ejirocodes/vue3-otp-input/blob/main/src/components/vue3-otp-input.vue) (lines 45-49):

| Event | Payload | When it fires |
|-------|---------|---------------|
| `update:value` | `string` | Every time the internal OTP string changes (used for `v-model`). |
| `on-change` | `string` | After each individual character is entered, deleted or pasted. |
| `on-complete` | `string` | When the OTP reaches the expected length (`numInputs`). |

## How on-change and on-complete Work Internally

### The on-change Event

Whenever a user interacts with the OTP fields, the component updates its internal reactive `otp` array. After each mutation, the code explicitly emits the `on-change` event with the joined string value (lines 106-108 in [`src/components/vue3-otp-input.vue`](https://github.com/ejirocodes/vue3-otp-input/blob/main/src/components/vue3-otp-input.vue)):

```typescript
emit("update:value", otp.value.join(""));
emit("on-change", otp.value.join(""));

```

This ensures parent components receive the current OTP state after every keystroke, paste action, or deletion.

### The on-complete Event

The component tracks completion through the `checkFilledAllInputs` helper function. When the joined `otp` string length matches the `numInputs` prop, the function emits `on-complete` (lines 80-82 in [`src/components/vue3-otp-input.vue`](https://github.com/ejirocodes/vue3-otp-input/blob/main/src/components/vue3-otp-input.vue)):

```typescript
const checkFilledAllInputs = () => {
  if (otp.value.join("").length === numInputs) {
    emit("on-complete", otp.value.join(""));
  }
};

```

This event is particularly useful for triggering automatic form submission or validation checks without requiring an explicit user action beyond completing the input.

## Implementation Examples

### Basic Event Listeners

The canonical usage pattern, as demonstrated in [`src/App.vue`](https://github.com/ejirocodes/vue3-otp-input/blob/main/src/App.vue) (lines 44-46), involves binding handlers directly in the parent template:

```vue
<template>
  <vue3-otp-input
    v-model:value="otp"
    :num-inputs="6"
    @on-change="handleOnChange"
    @on-complete="handleOnComplete"
  />
</template>

<script setup>
import { ref } from 'vue';
import Vue3OtpInput from 'vue3-otp-input';

const otp = ref('');
const handleOnChange = (value) => {
  console.log('Current OTP:', value);
};
const handleOnComplete = (value) => {
  console.log('Completed OTP:', value);
  // Trigger API verification here
};
</script>

```

### Accessing Component Methods with Event Handling

For scenarios requiring programmatic control alongside event listening, combine template refs with event handlers:

```vue
<script setup lang="ts">
import { ref } from 'vue';
import Vue3OtpInput from 'vue3-otp-input';

const otpRef = ref<InstanceType<typeof Vue3OtpInput> | null>(null);
const otp = ref('');

function onComplete(value: string) {
  console.log('Auto-submitting:', value);
  // API call logic
}

function clearInput() {
  otpRef.value?.clearInput();
}
</script>

<template>
  <button @click="clearInput">Clear OTP</button>
  <Vue3OtpInput
    ref="otpRef"
    v-model:value="otp"
    :num-inputs="4"
    @on-complete="onComplete"
  />
</template>

```

### Handling Numeric Input Types

When restricting input to numbers, the events emit after validation:

```vue
<template>
  <Vue3OtpInput
    v-model:value="numericOtp"
    input-type="number"
    :num-inputs="5"
    @on-change="val => console.log('Digits:', val)"
    @on-complete="val => verifyNumericCode(val)"
  />
</template>

```

The component validates pasted data against the `inputType` prop before emitting events (lines 19-27 in [`src/components/vue3-otp-input.vue`](https://github.com/ejirocodes/vue3-otp-input/blob/main/src/components/vue3-otp-input.vue)).

## Summary

- **`on-change`** fires after every character entry, deletion, or paste, emitting the current OTP string value.
- **`on-complete`** triggers only when the OTP length matches the `numInputs` prop, indicating the user has finished entering the code.
- Both events are declared in [`src/components/vue3-otp-input.vue`](https://github.com/ejirocodes/vue3-otp-input/blob/main/src/components/vue3-otp-input.vue) using `defineEmits` and can be bound using Vue's `@` shorthand.
- The events are useful for real-time validation, logging, and automatic form submission upon OTP completion.

## Frequently Asked Questions

### What is the difference between `update:value` and `on-change` in vue3-otp-input?

The `update:value` event is intended for `v-model` synchronization and fires whenever the OTP value changes, while `on-change` is a semantic event designed for parent components to react to user input changes. Both emit the current OTP string, but `on-change` is more appropriate for triggering side effects like validation or analytics tracking.

### How do I trigger an action when the user finishes entering the OTP?

Bind a handler to the `@on-complete` event, which fires when the joined OTP string length equals the `numInputs` prop. This event emits the final OTP value, making it ideal for triggering API verification calls or automatic form submission without requiring an additional button click.

### Can I listen to these events when using the component as a custom input?

Yes, the events are exposed through the component's `defineEmits` declaration and can be accessed regardless of how you import or register the component. Whether using global registration, local import, or wrapping the component in a custom input wrapper, the `@on-change` and `@on-complete` listeners function identically as long as the component instance is properly rendered in the template.

### Why is my on-complete event not firing?

The `on-complete` event only fires when the OTP value length strictly equals the `numInputs` prop value. If the event is not firing, verify that `numInputs` is set correctly and that the user has filled all input fields. Additionally, ensure you are listening to the correct event name (`@on-complete` with a hyphen, not camelCase) in your Vue template.