Сегодня применил Vuex на практике:
🔹 Вынес данные ссылок и навигации из локального data() компонентов в глобальный state.
🔹 Настроил доступ к ним через getters.
Теперь вся структура ссылок лежит в одном месте. Код компонентов стал чище, а масштабировать меню теперь намного проще — поправил в store, и всё обновилось везде.
Шаг за шагом к чистому и структурированному коду 🚀
🔹 Вынес данные ссылок и навигации из локального data() компонентов в глобальный state.
🔹 Настроил доступ к ним через getters.
Теперь вся структура ссылок лежит в одном месте. Код компонентов стал чище, а масштабировать меню теперь намного проще — поправил в store, и всё обновилось везде.
Шаг за шагом к чистому и структурированному коду 🚀
❤1
🚀 Переношу проект на Vue 3!
Решил отрефакторить свой старый проект и переписать его на Vue.
Что уже сделал:
Разбил верстку на компоненты (
Вынес данные участников в реактивный массив
Передал данные через
Подключил Роутеры.
Пока храню данные прямо в компоненте, позже планирую вынести всё в Pinia, чтобы сделать архитектуру ещё чище.
Решил отрефакторить свой старый проект и переписать его на Vue.
Что уже сделал:
Разбил верстку на компоненты (
TeamCard и Navbar).Вынес данные участников в реактивный массив
ref() и вывел карточки через v-for.Передал данные через
props в дочерний компонент.Подключил Роутеры.
Пока храню данные прямо в компоненте, позже планирую вынести всё в Pinia, чтобы сделать архитектуру ещё чище.
🚀 Переписал старый Bootstrap-проект на Vue 3!
Полноценно перевёл сайт в SPA всего за 2 часа. Это моё первое самостоятельное веб-приложение на Vue!
Что сделал в процессе:
Разбил верстку на независимые компоненты.
Настроил Vue Router с динамическим импортом страниц (lazy loading).
Реализовал передачу данных через
Следующий шаг вынести хранение данных из компонентов в Pinia.
Двигаемся дальше по плану! 💻🔥
Полноценно перевёл сайт в SPA всего за 2 часа. Это моё первое самостоятельное веб-приложение на Vue!
Что сделал в процессе:
Разбил верстку на независимые компоненты.
Настроил Vue Router с динамическим импортом страниц (lazy loading).
Реализовал передачу данных через
defineProps и директивы (v-for, :src, :class).Следующий шаг вынести хранение данных из компонентов в Pinia.
Двигаемся дальше по плану! 💻🔥
🔥 Сделал документацию для своей Gulp-сборки!
Написал подробную и понятную инструкцию по использованию моей Gulp сборки прямо в
Что умеет сборка:
⚡️ Автоматическая компиляция SCSS в CSS и автопрефиксы
🖼 Сжатие и конвертация изображений в WebP/JPG
🔤 Быстрая конвертация TTF-шрифтов в WOFF/WOFF2 в одну команду
🧩 HTML-инклюды для удобной модульной верстки
🎯 Автоматическая генерация SVG-спрайтов с визуальной шпаргалкой
🔄 Локальный сервер с автообновлением страницы (BrowserSync)
Зайти, посмотреть структуру, протестировать под свои проекты и оценить
Буду рад вашему фидбеку и звездочкам на репо! ⭐️ В скором времени сниму видеоразбор по этой сборке на YouTube.
Написал подробную и понятную инструкцию по использованию моей Gulp сборки прямо в
README.md на GitHub.Что умеет сборка:
⚡️ Автоматическая компиляция SCSS в CSS и автопрефиксы
🖼 Сжатие и конвертация изображений в WebP/JPG
🔤 Быстрая конвертация TTF-шрифтов в WOFF/WOFF2 в одну команду
🧩 HTML-инклюды для удобной модульной верстки
🎯 Автоматическая генерация SVG-спрайтов с визуальной шпаргалкой
🔄 Локальный сервер с автообновлением страницы (BrowserSync)
Зайти, посмотреть структуру, протестировать под свои проекты и оценить
README можно по ссылке: 👉 здесьБуду рад вашему фидбеку и звездочкам на репо! ⭐️ В скором времени сниму видеоразбор по этой сборке на YouTube.
Август всё! Вся база закрыта 💪
По планам на август закрыл вообще всё, что задумывал. Месяц выжал на максимум!
Под конец решил закрыть ещё одну мелкую, но частую рутину — написал пару лёгких
Дальше — сентябрь и новые задачи. Всех с наступающим! 🔥
По планам на август закрыл вообще всё, что задумывал. Месяц выжал на максимум!
Под конец решил закрыть ещё одну мелкую, но частую рутину — написал пару лёгких
.bat скриптов для автоматизации. Теперь не нужно руками прописывать одни и те же команды в консоли: запустил батник, и он сам всё делает и пушит на GitHub. Мелочь, а время и нервы экономят знатно.Дальше — сентябрь и новые задачи. Всех с наступающим! 🔥
🔥1
Перевожу проект с JS на TS. Наконец-то нормальный автокомплит в шаблонах Vue и никаких гаданий по поводу структуры данных.
Паттерн Assert Exhaustiveness в TypeScript: заставляем TS искать баги за нас
Представь: у тебя есть union-тип статусов заказа или валют, и ты обрабатываешь их через
Чтобы этого избежать, используется паттерн Assert Exhaustiveness:
Представь: у тебя есть union-тип статусов заказа или валют, и ты обрабатываешь их через
if или switch. Что произойдет, если через полгода в проект добавят новый статус, а ты забудешь добавить его обработку в функцию? Код тихо вернет undefined и сломает интерфейс.Чтобы этого избежать, используется паттерн Assert Exhaustiveness:
type Currency = 'RUB' | 'USD' | 'EUR' // Добавили EUR
// Вспомогательная функция для проверки исчерпываемости
// "value: never" работает в редакторе , и подсвечивает ошибку, если не обработали вариант
function assertExhaustiveness(value: never): never {
// Работает на сервере
throw new Error(`Необработанный вариант: ${JSON.stringify(value)}`);
}
function getCurrencyChar(currency: Currency) {
if (currency === 'RUB') return '₽';
if (currency === 'USD') return '$';
// ТУТ TS ВЫДАСТ ОШИБКУ КОМПИЛЯЦИИ:
// Argument of type 'string' (EUR) is not assignable to parameter of type 'never'.
// TS буквально заставляет тебя написать еще один if для 'EUR'!
// Если все варианты обработаны, сюды доходит только 'never'
return assertExhaustiveness(currency)
}
❤1
Перегрузки функций в TypeScript:
Представьте, что функция может принимать разные варианты аргументов (например, просто
Если просто написать
Перегрузки функций решают эту проблему! Они задают четкое правило:
// Реализовываем перегрузку
function axios(url: string): string;
function axios(url: string, sett: { method: string }): number;
function axios(sett: { url: string; method: string }): string;
function axios(urlOrSett: string | {url: string, method: string}, sett?: {method: string}): string | number {
if (typeof urlOrSett === 'string') {
if (sett) {
return 200; // Case 2: url + sett => number
}
return 'Data from URL'; // Case 1: url => string
}
return 'Data from config'; // Case 3: config object => string
}
const a1 = axios('/url')
const a2 = axios('/url', { method: 'GET'})
const a3 = axios({url: '/url', method: 'GET'})
Представьте, что функция может принимать разные варианты аргументов (например, просто
string или объект настроек).Если просто написать
function axios(...): string | number, TypeScript вернет тип string | number при любом вызове. В итоге придется везде писать лишние проверки if (typeof ... === 'string')Перегрузки функций решают эту проблему! Они задают четкое правило:
Если передали аргументы типа A — возвращаем строго тип B, а не неопределенный union!
👍1
Дженерики в TypeScript делают код гибким, но иногда эту гибкость нужно ограничить. Для этого используется
В примере ниже мы явно говорим компилятору:
В итоге мы получили безопасную функцию, которая не принимает лишний мусор вроде
extends (Generic Constraints).В примере ниже мы явно говорим компилятору:
T может быть чем угодно, НО только из числа string или number.// extends сужает(ограничивает) типы данных в дженерике
// мы можем вызывать эту функцию только со строками или числами
function wrapInArray<T extends string | number>(value: T): T[] {
return Array.isArray(value) ? value : [value];
};
// Все работает
wrapInArray(1);
wrapInArray('hello');
// Ошибка: мы не можем вызывать с типом данных boolean
// wrapInArray(true);
В итоге мы получили безопасную функцию, которая не принимает лишний мусор вроде
boolean или объектов, сохраняя при этом точную типизацию возвращаемого значения. 🔥Репозиторий создан, окружение поднято — к работе готов! 🚀 Начинаем переписывать приложение с чистого HTML/JavaScript на Vue 🥳