← Back to Laravel and Vue foundation team

Skill · Version 1.0.0

Reliable Vue forms and requests

Keeps Vue forms and data-loading flows predictable when networks are slow, requests overlap or saving fails.

vue-async-forms

Team members using this skill

See how it helps

When is it useful?

Use when fast typing, changing filters or repeated submit clicks can show the wrong data or lose a form draft.

What does it help you do?

  • Ignores obsolete responses and separates initial loading, refreshing, empty and error states.
  • Prevents repeated submissions and restores earlier state after failed optimistic changes.
  • Preserves dynamic form rows and connects server errors to the correct fields and steps.

Try asking this

Build a multistep order form with editable line items. Keep entries after a failed save, focus the invalid step and prevent double submission on a slow connection. Reject a line item on the second step after a slow response. Keep other rows and their identities intact, and return focus to the field needing correction.

Detailed documentation

Read the skill’s original instructions, examples and checks in their authored language.

Details…Show less

Async UI & Complex Forms

Make every asynchronous operation and form workflow resilient to slow networks, rapid user input, out-of-order responses, interruptions and server errors.

1. Preventing stale responses and race conditions

  • Whenever a user can trigger overlapping requests (typing in search boxes, switching tabs/filters rapidly, changing route params, clicking pagination), prevent an older slow response from overwriting a newer result:
    • Pass an AbortController signal to fetch / axios and call controller.abort() inside onWatcherCleanup (Vue 3.5+) or watch's onCleanup((_, __, onCleanup) => onCleanup(() => controller.abort())), and on unmount.
    • Or increment a local requestId counter before each request and ignore any response where currentId !== requestId before mutating reactive state (data, error, isLoading).
  • Ignore AbortError when setting user-facing error state so canceled requests never flash an error banner.

2. Explicit async UI states

  • Model async status explicitly (idle, loading, error, success) rather than ambiguous booleans that allow contradictory states (such as showing both an error banner and a loading spinner or a flash of "No items found" before the first request starts).
  • Distinguish initial load (skeleton matching the layout) from background refresh / filter update (keep existing data visible with aria-busy="true" or a subtle progress indicator instead of blanking the screen).
  • On error, preserve the user's input, explain what failed clearly, and offer a working retry or recovery action.

3. Double-submit protection, retries and optimistic UI

  • Guard every mutation action against double clicks or repeated Enter presses:
    • Check if (isSubmitting.value) return at the start of the handler, set isSubmitting.value = true in try, and reset in finally.
    • Disable or mark the submit control busy while in flight.
  • For optimistic updates (toggles, reordering, quick deletes), snapshot the previous state before applying the optimistic mutation, roll back to the snapshot if the request fails, and show a clear error toast.

4. Complex, dynamic and multi-step forms

  • Give dynamic form array rows (line items,repeater fields) a stable unique id generated at row creation (crypto.randomUUID() or counter) for :key — never :key="index", which corrupts field state and validation errors when rows are inserted or removed.
  • Separate field-level validation timing: validate eagerly only after a field has been blurred (touched) or after the first submit attempt, and clear a field's error as soon as the user corrects it.
  • Map server-side field validation errors (422) back onto the corresponding fields, open the step/tab containing the first invalid field in multi-step forms, and move focus to the first invalid input (aria-invalid="true", aria-describedby).
  • Track dirty state against the initial snapshot so Cancel, modal close or route leave warns before losing unsaved work.

Before you finish

  • Rapid filter/tab/param changes cancel or ignore stale responses via AbortController or request tokens.
  • Mutations block duplicate submissions while in flight and preserve user input when a request fails.
  • Dynamic form rows use stable unique keys, and server/client validation errors link to fields and focus the first invalid control.
  • Loading, empty, error, retry and dirty-leave states all work predictably.

Included files 2

  • LICENSE.txt
  • SKILL.md