vue-application-structure

安装量: 252
排名: #8394

安装

npx skills add https://github.com/aj-geddes/useful-ai-prompts --skill vue-application-structure

Vue Application Structure Overview

Build well-organized Vue 3 applications using Composition API, proper file organization, and TypeScript for type safety and maintainability.

When to Use Large-scale Vue applications Component library development Reusable composable hooks Complex state management Performance optimization Implementation Examples 1. Vue 3 Composition API Component // useCounter.ts (Composable) import { ref, computed } from 'vue';

export function useCounter(initialValue = 0) { const count = ref(initialValue);

const doubled = computed(() => count.value * 2); const increment = () => count.value++; const decrement = () => count.value--; const reset = () => count.value = initialValue;

return { count, doubled, increment, decrement, reset }; }

// Counter.vue

<script setup lang="ts"> import { useCounter } from './useCounter'; const { count, doubled, increment, decrement, reset } = useCounter(0); </script> <style scoped> .counter { padding: 20px; border: 1px solid #ccc; } </style>
  1. Async Data Fetching Composable // useFetch.ts import { ref, computed, onMounted } from 'vue';

interface UseFetchOptions { immediate?: boolean; }

export function useFetch( url: string, options: UseFetchOptions = {} ) { const data = ref(null); const loading = ref(false); const error = ref(null);

const isLoading = computed(() => loading.value); const hasError = computed(() => error.value !== null);

const fetch = async () => { loading.value = true; error.value = null;

try {
  const response = await globalThis.fetch(url);
  if (!response.ok) throw new Error(`HTTP ${response.status}`);
  data.value = await response.json();
} catch (e) {
  error.value = e instanceof Error ? e : new Error(String(e));
} finally {
  loading.value = false;
}

};

const refetch = () => fetch();

if (options.immediate !== false) { onMounted(fetch); }

return { data, loading: isLoading, error: hasError, fetch, refetch }; }

// UserList.vue

<script setup lang="ts"> import { useFetch } from './useFetch'; interface User { id: number; name: string; } const { data, loading, error, refetch } = useFetch('/api/users'); </script>
  1. Component Organization Structure src/ ├── components/ │ ├── common/ │ │ ├── Button.vue │ │ ├── Card.vue │ │ └── Modal.vue │ ├── forms/ │ │ ├── FormInput.vue │ │ └── FormSelect.vue │ └── layouts/ │ ├── Header.vue │ └── Sidebar.vue ├── composables/ │ ├── useCounter.ts │ ├── useFetch.ts │ └── useForm.ts ├── services/ │ ├── api.ts │ └── auth.ts ├── stores/ │ ├── user.ts │ └── auth.ts ├── types/ │ ├── models.ts │ └── api.ts ├── App.vue └── main.ts

  2. Form Handling Composable // useForm.ts import { ref, reactive } from 'vue';

interface UseFormOptions { onSubmit: (data: T) => Promise; initialValues: T; }

export function useForm>( options: UseFormOptions ) { const formData = reactive(options.initialValues); const errors = reactive>({}); const isSubmitting = ref(false);

const handleSubmit = async (e?: Event) => { e?.preventDefault(); isSubmitting.value = true;

try {
  await options.onSubmit(formData);
} catch (error) {
  const err = error as any;
  if (err.fieldErrors) {
    Object.assign(errors, err.fieldErrors);
  }
} finally {
  isSubmitting.value = false;
}

};

const reset = () => { Object.assign(formData, options.initialValues); Object.keys(errors).forEach(key => delete errors[key]); };

return { formData, errors, isSubmitting, handleSubmit, reset }; }

// LoginForm.vue

<script setup lang="ts"> import { useForm } from './useForm'; const { formData, errors, isSubmitting, handleSubmit } = useForm({ initialValues: { email: '', password: '' }, onSubmit: async (data) => { const response = await fetch('/api/login', { method: 'POST', body: JSON.stringify(data) }); if (!response.ok) throw new Error('Login failed'); } }); </script>
  1. Pinia Store (State Management) // stores/user.ts import { defineStore } from 'pinia'; import { ref, computed } from 'vue';

interface User { id: number; name: string; email: string; }

export const useUserStore = defineStore('user', () => { const user = ref(null); const isLoading = ref(false);

const isLoggedIn = computed(() => user.value !== null);

const fetchUser = async (id: number) => { isLoading.value = true; try { const response = await fetch(/api/users/${id}); user.value = await response.json(); } finally { isLoading.value = false; } };

const logout = () => { user.value = null; };

return { user, isLoading, isLoggedIn, fetchUser, logout }; });

// Usage in component import { useUserStore } from '@/stores/user';

export default { setup() { const userStore = useUserStore(); userStore.fetchUser(1); return { userStore }; } };

Best Practices Organize by features or domains Use Composition API for logic reuse Extract composables for shared logic Use TypeScript for type safety Implement proper error handling Keep components focused and testable Use Pinia for state management Resources Vue 3 Documentation Vue Composition API Pinia State Management

返回排行榜