Use Cases (अपडेट: 2/6/2026)

Claude Code से Vue 3 Development: TypeScript, Pinia और Vitest Guide

Claude Code के साथ Vue 3, TypeScript, form, Pinia, composable और Vitest को practical workflow में इस्तेमाल करें।

Claude Code से Vue 3 Development: TypeScript, Pinia और Vitest Guide

Vue 3 project में Claude Code का असली फायदा सिर्फ component generate करने में नहीं है। असली value तब मिलती है जब यह existing SFC पढ़ता है, TypeScript types बचाए रखता है, repeated logic को composable में निकालता है, shared state को Pinia में रखता है, और अंत में Vitest tests जोड़ता है। यही workflow production projects में सबसे ज्यादा काम आता है।

Vue flexible framework है, इसलिए code style भी जल्दी mix हो जाता है। एक ही repository में Options API, Composition API, script setup, Pinia, पुराने Vuex patterns, Nuxt conventions और local helpers साथ मिल सकते हैं। अगर prompt सिर्फ “Vue form बना दो” है, तो Claude Code चलने वाला code बना सकता है, पर वह team की architecture boundary से match न करे।

यह guide Claude Code + Vue 3 + TypeScript के practical use cases दिखाती है: existing Vue refactor, form implementation, Pinia state management, composable extraction और Vitest test addition। Technical reference के लिए Vue TypeScript with Composition API, Pinia docs और Vitest guide देखें। Related Claude Code topics के लिए TypeScript Tips और Testing Strategy Guide भी उपयोगी हैं।

Project assumptions

यह article Vue 3, TypeScript, Vite, Pinia और Vitest based app मानकर चलता है। Use cases में admin dashboard, support desk, booking system, internal approval flow और content management शामिल हो सकते हैं। ऐसे apps में form state, filters, pagination, shared data और tests सबसे ज्यादा maintenance cost पैदा करते हैं।

Claude Code को काम देने से पहले harness दें। Harness का मतलब है agent के लिए safe working frame: कौन सी files edit कर सकता है, कौन से rules follow करने हैं, क्या नहीं बदलना है, कौन से commands चलाने हैं, और review में क्या explain करना है। बिना harness के Claude Code local problem solve करते हुए any, unwanted UI text change या गलत state boundary introduce कर सकता है।

SituationClaude Code का कामHuman decision
Existing Vue refactorSFC पढ़ना, duplication हटाना, types जोड़नाUI compatibility और release risk
FormLocal state, validation, submit flowError messages और API contract
PiniaStore types, getters, actions, testsPersistence और ownership
ComposableFilter, pagination, reusable logicReuse सच में चाहिए या नहीं
TestsNormal, error और regression casesCoverage level

Architecture overview

Code examples बढ़ते ही सबसे जरूरी सवाल होता है: responsibility कहाँ रखनी है? Clear boundary से Claude Code का diff review करना आसान होता है।

flowchart LR
  A[Vue SFC] --> B[Composable]
  A --> C[Pinia Store]
  B --> D[Vitest]
  C --> D
  E[Claude Code Prompt] --> A
  E --> B
  E --> C
  E --> D

SFC screen और user events रखता है। Composable reusable reactive logic रखता है, जैसे filtering और pagination। Pinia store shared application state रखता है। Vitest उन behaviors को protect करता है जिन्हें टूटना नहीं चाहिए।

Vue 3 + TypeScript setup

New experiment के लिए official Vue scaffolding से शुरुआत करें। Existing repository में पहले typecheck और unit tests पास होने चाहिए, ताकि Claude Code के changes को clean baseline से compare किया जा सके।

npm create vue@latest support-desk-vue -- --typescript --router --pinia --vitest
cd support-desk-vue
npm install
npm run dev

Prompt में सिर्फ “modern Vue app बनाओ” न लिखें। Package manager, Vue Router, Pinia, और test command साफ लिखें। Existing app में Claude Code को पहले package.json, vite.config.ts, tsconfig.app.json, src/components और src/stores पढ़ने को कहें।

Use case 1: typed form SFC

Form अच्छा first target है क्योंकि इसमें v-model, props, emit, validation, saving state और store action साथ आते हैं। नीचे का example src/components/TicketForm.vue में रखा जा सकता है। यह props mutate नहीं करता, editable values को local ref में रखता है, और save के बाद ticket id emit करता है।

<script setup lang="ts">
import { computed, ref } from 'vue';
import { useTicketStore, type TicketPriority } from '@/stores/ticketStore';

const props = withDefaults(
  defineProps<{
    initialTitle?: string;
    defaultPriority?: TicketPriority;
  }>(),
  {
    initialTitle: '',
    defaultPriority: 'medium',
  },
);

const emit = defineEmits<{
  submitted: [id: string];
}>();

const store = useTicketStore();
const title = ref(props.initialTitle);
const description = ref('');
const priority = ref<TicketPriority>(props.defaultPriority);
const touched = ref(false);

const titleError = computed(() => {
  if (!touched.value) return '';
  if (title.value.trim().length < 5) return 'Use at least 5 characters.';
  return '';
});

const descriptionError = computed(() => {
  if (!touched.value) return '';
  if (description.value.trim().length < 20) return 'Use at least 20 characters.';
  return '';
});

const canSubmit = computed(() => {
  return (
    title.value.trim().length >= 5 &&
    description.value.trim().length >= 20 &&
    !store.isSaving
  );
});

async function submit() {
  touched.value = true;
  if (!canSubmit.value) return;

  const ticket = await store.saveTicket({
    title: title.value.trim(),
    description: description.value.trim(),
    priority: priority.value,
  });

  title.value = '';
  description.value = '';
  priority.value = props.defaultPriority;
  touched.value = false;
  emit('submitted', ticket.id);
}
</script>

<template>
  <form class="ticket-form" @submit.prevent="submit">
    <label>
      Title
      <input v-model="title" name="title" @blur="touched = true" />
    </label>
    <p v-if="titleError" class="error">{{ titleError }}</p>

    <label>
      Description
      <textarea v-model="description" name="description" @blur="touched = true" />
    </label>
    <p v-if="descriptionError" class="error">{{ descriptionError }}</p>

    <label>
      Priority
      <select v-model="priority" name="priority">
        <option value="low">Low</option>
        <option value="medium">Medium</option>
        <option value="high">High</option>
      </select>
    </label>

    <button type="submit" :disabled="!canSubmit">
      {{ store.isSaving ? 'Saving...' : 'Create ticket' }}
    </button>
  </form>
</template>

Claude Code को ऐसे component के लिए request करते समय negative rules भी लिखें: props mutate न करें, any introduce न करें, UI library न जोड़ें, API details component में न डालें। इससे cleanup कम होता है।

Use case 2: Pinia store

अगर ticket list कई screens में इस्तेमाल होगी, तो SFC को पूरा state नहीं रखना चाहिए। Pinia में list, saving flag, open tickets getter और actions रखें।

import { computed, ref } from 'vue';
import { defineStore } from 'pinia';

export type TicketPriority = 'low' | 'medium' | 'high';
export type TicketStatus = 'open' | 'closed';

export interface Ticket {
  id: string;
  title: string;
  description: string;
  priority: TicketPriority;
  status: TicketStatus;
  createdAt: string;
}

export type NewTicketInput = Pick<Ticket, 'title' | 'description' | 'priority'>;

export const useTicketStore = defineStore('tickets', () => {
  const tickets = ref<Ticket[]>([]);
  const isSaving = ref(false);

  const openTickets = computed(() => {
    return tickets.value.filter((ticket) => ticket.status === 'open');
  });

  function addTicket(input: NewTicketInput) {
    const ticket: Ticket = {
      id: crypto.randomUUID(),
      ...input,
      status: 'open',
      createdAt: new Date().toISOString(),
    };

    tickets.value.unshift(ticket);
    return ticket;
  }

  async function saveTicket(input: NewTicketInput) {
    isSaving.value = true;
    try {
      await new Promise((resolve) => setTimeout(resolve, 150));
      return addTicket(input);
    } finally {
      isSaving.value = false;
    }
  }

  function closeTicket(id: string) {
    const ticket = tickets.value.find((item) => item.id === id);
    if (ticket) ticket.status = 'closed';
  }

  return {
    tickets,
    isSaving,
    openTickets,
    addTicket,
    saveTicket,
    closeTicket,
  };
});

Production में saveTicket typed API client call करेगा। फिर भी पहले store model review करें, फिर network जोड़ें, फिर error handling और retry add करें। इससे review छोटे steps में होता है।

Use case 3: composable extraction

Composable Vue reactive logic की reusable function है। आसान शब्दों में, screen से निकाला गया logic part। Search, priority filter और pagination इसके लिए अच्छे candidates हैं।

import { computed, ref, watch, type Ref } from 'vue';
import type { Ticket, TicketPriority } from '@/stores/ticketStore';

export function useFilteredTickets(tickets: Ref<Ticket[]>) {
  const query = ref('');
  const selectedPriority = ref<TicketPriority | 'all'>('all');
  const currentPage = ref(1);
  const pageSize = ref(10);

  const filteredTickets = computed(() => {
    const normalizedQuery = query.value.trim().toLowerCase();

    return tickets.value.filter((ticket) => {
      const matchesQuery =
        normalizedQuery.length === 0 ||
        ticket.title.toLowerCase().includes(normalizedQuery) ||
        ticket.description.toLowerCase().includes(normalizedQuery);

      const matchesPriority =
        selectedPriority.value === 'all' ||
        ticket.priority === selectedPriority.value;

      return matchesQuery && matchesPriority;
    });
  });

  const totalPages = computed(() => {
    return Math.max(1, Math.ceil(filteredTickets.value.length / pageSize.value));
  });

  const pagedTickets = computed(() => {
    const start = (currentPage.value - 1) * pageSize.value;
    return filteredTickets.value.slice(start, start + pageSize.value);
  });

  watch([query, selectedPriority], () => {
    currentPage.value = 1;
  });

  return {
    query,
    selectedPriority,
    currentPage,
    pageSize,
    filteredTickets,
    pagedTickets,
    totalPages,
  };
}

यहाँ watch सिर्फ एक side effect करता है: filters बदलें तो page 1 पर लौटे। बाकी derived values computed में हैं। Prompt में लिखें: derived values के लिए computed, side effects के लिए watch

Use case 4: Vitest tests

Implementation तेज होने पर regression tests और जरूरी हो जाते हैं। Pinia store से शुरू करना अच्छा है क्योंकि यह business behavior के करीब है और DOM tests से कम fragile है।

import { createPinia, setActivePinia } from 'pinia';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { useTicketStore } from './ticketStore';

describe('useTicketStore', () => {
  beforeEach(() => {
    setActivePinia(createPinia());
    vi.stubGlobal('crypto', {
      randomUUID: () => 'ticket-1',
    });
  });

  it('adds a new open ticket', () => {
    const store = useTicketStore();

    const ticket = store.addTicket({
      title: 'Cannot submit expense form',
      description: 'The submit button stays disabled after all fields are filled.',
      priority: 'high',
    });

    expect(ticket.id).toBe('ticket-1');
    expect(store.tickets).toHaveLength(1);
    expect(store.openTickets).toHaveLength(1);
  });

  it('closes an existing ticket', () => {
    const store = useTicketStore();
    const ticket = store.addTicket({
      title: 'Profile image is broken',
      description: 'The image URL returns 404 on the account settings page.',
      priority: 'medium',
    });

    store.closeTicket(ticket.id);

    expect(store.openTickets).toHaveLength(0);
    expect(store.tickets[0]?.status).toBe('closed');
  });
});

“कुछ tests जोड़ो” मत कहें। Behaviors specify करें: short input, valid input, saving state, success, failure और Pinia state change। इससे useful tests मिलते हैं।

Existing Vue refactor prompt

Existing code में बड़ा rewrite risky होता है। पहले Claude Code से component पढ़वाकर risks लिखवाएँ, फिर types fix करें, एक composable extract करें, जरूरत हो तो Pinia सुधारें, और अंत में tests जोड़ें।

You are working in a Vue 3 + TypeScript + Pinia project.

Goal:
Refactor the ticket form so validation logic is typed, reusable, and covered by Vitest.

Allowed files:
- src/components/TicketForm.vue
- src/composables/useFilteredTickets.ts
- src/stores/ticketStore.ts
- src/stores/ticketStore.test.ts

Rules:
- Use <script setup lang="ts">.
- Do not mutate props directly.
- Do not introduce any.
- Prefer computed for derived values.
- Use watch only for explicit side effects.
- Keep UI text unchanged unless a validation message is missing.

Verification:
- npm run typecheck
- npm run test:unit

After editing, explain the risk areas and the tests you added.

यह prompt Claude Code के decision और human decision को अलग करता है। Extraction, types और test draft tool कर सकता है। UI text, API contract, accessibility और release timing humans को check करना चाहिए।

Common pitfalls

पहला pitfall है Options API और Composition API को बिना plan mix करना। Vue 3 दोनों support करता है, लेकिन एक component में data, methods, setup और script setup साथ हों तो review मुश्किल हो जाता है।

दूसरा pitfall है ref और reactive को गलत समझना। Primitive values, arrays और replace होने वाले values के लिए ref usually आसान है। reactive cohesive objects के लिए ठीक है, पर destructuring में confusion हो सकता है।

तीसरा pitfall है props mutate करना। Child component को parent state चुपचाप change नहीं करना चाहिए। Local ref, emit, या team-approved defineModel pattern इस्तेमाल करें।

चौथा pitfall है watch overuse करना। Derived values computed में रखें। watch route sync, page reset, API call या storage write जैसे side effects तक सीमित रखें।

पाँचवाँ pitfall है types का any बन जाना। Claude Code type error हटाने के लिए as any डाल सकता है। Review में any, unknown, assertions और empty array inference देखें।

छठा pitfall है SFC को बहुत ज्यादा split करना। Reuse न होने वाले छोटे components props और emits बढ़ाते हैं। पहले logic composable में निकालें, UI तभी split करें जब actual reuse या independent meaning हो।

सातवाँ pitfall है tests की कमी। Generated code clean दिख सकता है, लेकिन edge cases miss कर सकता है। Form में short input, valid submit, saving, success, failure और store state change test करें।

Practical workflow और CTA

Real repository में “पूरा screen बना दो” से शुरुआत न करें। Claude Code से पहले current component के risks लिखवाएँ। फिर छोटा change करें, typecheck और tests चलाएँ, फिर next step लें। Small diffs review quality बढ़ाते हैं।

Team adoption के लिए CLAUDE.md में rules लिखें: Vue में script setup, shared state में Pinia setup store, derived values में computed, side effects में watch, और verification में npm run typecheck तथा npm run test:unit। ClaudeCodeLab की Claude Code training और consultation में इन rules, prompts और review checklist को real repository के हिसाब से बनाया जा सकता है।

Summary

Claude Code Vue 3 refactor, form, Pinia, composable और tests को तेज कर सकता है। Quality prompt boundary पर निर्भर करती है: कौन सी files edit होंगी, कौन सा Vue style होगा, क्या नहीं बदलेगा, और verification कैसे होगी।

Beginners एक SFC, एक composable, एक store और एक test file से शुरू करें। यह छोटा loop Vue का mental model सिखाता है और production-like code देता है।

वास्तव में आजमाने का परिणाम

मैंने इस workflow को छोटे Vue 3 + TypeScript project में आजमाया। Form, store, composable और tests को एक ही request में मांगने पर diff बड़ा हो गया और review slow हुआ। SFC, Pinia, composable, Vitest के steps में बाँटने पर changes पढ़ना आसान हुआ। सबसे useful constraints थे: props mutate न करें, any introduce न करें, और derived values के लिए computed use करें। इसके बाद npm run typecheck और npm run test:unit से verification साफ हो गई।

#Claude Code #Vue.js #Nuxt.js #Pinia #Composition API
मुफ़्त

मुफ़्त PDF: Claude Code cheatsheet

Email डालें और commands, review habits तथा safe workflow वाली एक-page PDF पाएँ.

हम आपका data सुरक्षित रखते हैं और spam नहीं भेजते.

Masa

लेखक के बारे में

Masa

Claude Code workflow और team adoption पर काम करने वाला engineer.