# JavaScript/TypeScript Code Style Rules ## JavaScript Version - ES2020+ features - Modern async/await - Optional chaining (`?.`) - Nullish coalescing (`??`) - Template literals ## Code Style ### Variable Declarations ```javascript // ✅ Используй const по умолчанию const customers = []; const totalRecords = 0; // ✅ let только когда нужно переназначение let currentPage = 1; currentPage = 2; // ❌ Не используй var var oldVariable = 'bad'; ``` ### Arrow Functions ```javascript // ✅ Предпочтительно для коротких функций const filtered = items.filter(item => item.isActive); // ✅ Для методов объектов const api = { get: async (url) => { return await fetch(url); } }; // ✅ Для сложной логики - обычные функции function complexCalculation(data) { // много строк кода return result; } ``` ### Template Literals ```javascript // ✅ Предпочтительно const message = `User ${userId} not found`; const url = `${baseUrl}/api/${endpoint}`; // ❌ Не используй конкатенацию const message = 'User ' + userId + ' not found'; ``` ### Optional Chaining ```javascript // ✅ Используй optional chaining const name = user?.profile?.name; const count = data?.items?.length ?? 0; // ❌ Избегай длинных проверок const name = user && user.profile && user.profile.name; ``` ### Nullish Coalescing ```javascript // ✅ Используй ?? для значений по умолчанию const page = params.page ?? 1; const name = user.name ?? 'Unknown'; // ❌ Не используй || для чисел/булевых const page = params.page || 1; // 0 будет заменено на 1 ``` ### Destructuring ```javascript // ✅ Используй деструктуризацию const { data, totalRecords } = response.data; const [first, second] = items; // ✅ В параметрах функций function processUser({ id, name, email }) { // ... } // ✅ С значениями по умолчанию const { page = 1, limit = 20 } = params; ``` ### Async/Await ```javascript // ✅ Предпочтительно async function loadCustomers() { try { const response = await apiGet('getCustomers', params); return response.data; } catch (error) { console.error('Error:', error); throw error; } } // ❌ Избегай .then() цепочек function loadCustomers() { return apiGet('getCustomers', params) .then(response => response.data) .catch(error => console.error(error)); } ``` ## Vue.js 3 Composition API ### Script Setup ```vue ``` ### Reactive State ```javascript // ✅ Используй ref для примитивов const count = ref(0); const name = ref(''); // ✅ Используй reactive для объектов import { reactive } from 'vue'; const state = reactive({ customers: [], loading: false }); // ✅ Или ref для объектов (предпочтительно) const state = ref({ customers: [], loading: false }); ``` ### Computed Properties ```javascript // ✅ Используй computed для производных значений const filteredCustomers = computed(() => { return customers.value.filter(c => c.isActive); }); // ❌ Не используй методы для вычислений function filteredCustomers() { return customers.value.filter(c => c.isActive); } ``` ### Props ```vue ``` ### Emits ```vue ``` ## Pinia Stores ```javascript // ✅ Используй setup stores import { defineStore } from 'pinia'; import { ref, computed } from 'vue'; export const useCustomersStore = defineStore('customers', () => { const customers = ref([]); const loading = ref(false); const totalRecords = computed(() => customers.value.length); async function loadCustomers() { loading.value = true; try { const result = await apiGet('getCustomers'); customers.value = result.data || []; } finally { loading.value = false; } } return { customers, loading, totalRecords, loadCustomers }; }); ``` ## Error Handling ```javascript // ✅ Всегда обрабатывай ошибки async function loadData() { try { const result = await apiGet('endpoint'); if (result.success) { return result.data; } else { throw new Error(result.error); } } catch (error) { console.error('Failed to load data:', error); toast.error('Не удалось загрузить данные'); throw error; } } ``` ## Naming Conventions ### Variables and Functions ```javascript // ✅ camelCase const customerData = {}; const totalRecords = 0; function loadCustomers() {} // ✅ Константы UPPER_SNAKE_CASE const MAX_RETRIES = 3; const API_BASE_URL = '/api'; ``` ### Components ```vue ``` ### Files ```javascript // ✅ kebab-case для файлов // customers-view.vue // http-utils.js // customer-service.js ``` ## Imports ```javascript // ✅ Группируй импорты // 1. Vue core import { ref, computed, onMounted } from 'vue'; // 2. Third-party import { apiGet } from '@/utils/http.js'; import { useToast } from 'primevue'; // 3. Local components import CustomerCard from '@/components/CustomerCard.vue'; // 4. Types (если TypeScript) import type { Customer } from '@/types'; ``` ## TypeScript (где используется) ```typescript // ✅ Используй типы interface Customer { id: number; name: string; email?: string; } function getCustomer(id: number): Promise { return apiGet(`customers/${id}`); } ```