🚀 Хотите стать мастером Vue? Присоединяйся к открытому вебинару!
Вы знаете JavaScript, но не понимаете, как работает Vue? Хотите научиться использовать его для создания динамичных приложений?
🔥8 июля в 20.00 мск. приглашаем на открытый урок “Как быстро освоить Vue, если уже знаешь JavaScript”, на котором разберем:
- создание компонентов с реактивностью и передача данных;
- работу с директивами (v-if, v-for, v-model);
- сборку мини-приложения с динамическими данными.
Вы научитесь использовать Vue для создания интерфейсов, разберетесь в компонентах и реактивности, а также получите основы для работы над реальными проектами. 🛠
👉 Регистрируйтесь по ссылке: https://vk.cc/cNbBVQ
Бесплатное занятие приурочено к старту курса “Vue.js разработчик”, на котором можно глубже погрузиться в особенности фреймворка, научиться работать с его инструментами и создавать реальные проекты.
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Вы знаете JavaScript, но не понимаете, как работает Vue? Хотите научиться использовать его для создания динамичных приложений?
🔥8 июля в 20.00 мск. приглашаем на открытый урок “Как быстро освоить Vue, если уже знаешь JavaScript”, на котором разберем:
- создание компонентов с реактивностью и передача данных;
- работу с директивами (v-if, v-for, v-model);
- сборку мини-приложения с динамическими данными.
Вы научитесь использовать Vue для создания интерфейсов, разберетесь в компонентах и реактивности, а также получите основы для работы над реальными проектами. 🛠
👉 Регистрируйтесь по ссылке: https://vk.cc/cNbBVQ
Бесплатное занятие приурочено к старту курса “Vue.js разработчик”, на котором можно глубже погрузиться в особенности фреймворка, научиться работать с его инструментами и создавать реальные проекты.
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
📚 Шпаргалка по
1. Импорт
Прежде всего, импортируйте его из React:
2. Объявление переменной состояния
Внутри вашего функционального компонента вызовите
*
*
*
Пример:
3. Обновление состояния
Для изменения состояния всегда используйте функцию
Важно: Когда вы вызываете функцию обновления состояния (
4. Функциональное обновление состояния (когда новое состояние зависит от предыдущего)
Если новое состояние зависит от предыдущего, используйте функцию обратного вызова в
Здесь
5. Несколько переменных состояния
Вы можете использовать
Когда использовать
* Для любого изменяемого значения, которое должно вызывать перерендер компонента при изменении.
* Для данных, специфичных для этого компонента.
Ключевые моменты:
*
* Обновление состояния асинхронно. React может группировать несколько обновлений для оптимизации.
* При обновлении объекта или массива всегда создавайте новую копию, а не мутируйте существующую.
Используйте эту шпаргалку, чтобы уверенно работать с состоянием в ваших React-приложениях!
👉 @frontend_1
useState
в React: Управление состоянием в функциональных компонентахuseState
— это хук, который позволяет добавлять состояние в функциональные компоненты React. Это основа для создания интерактивных и динамичных интерфейсов!1. Импорт
useState
Прежде всего, импортируйте его из React:
import React, { useState } from 'react';
2. Объявление переменной состояния
Внутри вашего функционального компонента вызовите
useState()
:
const [stateVariable, setStateVariable] = useState(initialValue);
*
stateVariable
: Текущее значение состояния. Вы можете назвать её как угодно.*
setStateVariable
: Функция для обновления этого состояния. По соглашению, её называют set
+ имя переменной состояния (например, setCount
, setName
).*
initialValue
: Начальное значение состояния. Оно будет использовано только при первом рендере компонента. Может быть любым типом данных: число, строка, булево, объект, массив, null
.Пример:
const [count, setCount] = useState(0); // Число
const [name, setName] = useState('Alice'); // Строка
const [isActive, setIsActive] = useState(false); // Булево
const [user, setUser] = useState({ id: 1, name: 'Bob' }); // Объект
const [items, setItems] = useState([]); // Массив
3. Обновление состояния
Для изменения состояния всегда используйте функцию
setStateVariable
. Никогда не изменяйте stateVariable
напрямую!
// Увеличить счетчик
setCount(count + 1);
// Изменить имя
setName('Charlie');
// Переключить булево
setIsActive(!isActive);
// Обновить объект (важно: создавайте новый объект!)
setUser({ ...user, name: 'David' });
// Добавить элемент в массив (важно: создавайте новый массив!)
setItems([...items, 'New Item']);
Важно: Когда вы вызываете функцию обновления состояния (
setCount
, setName
и т.д.), React перерендерит компонент с новым значением.4. Функциональное обновление состояния (когда новое состояние зависит от предыдущего)
Если новое состояние зависит от предыдущего, используйте функцию обратного вызова в
setStateVariable
. Это гарантирует, что вы работаете с самым актуальным состоянием, особенно в асинхронных операциях или при пакетном обновлении:
setCount(prevCount => prevCount + 1);
Здесь
prevCount
— это гарантированно предыдущее значение count
.5. Несколько переменных состояния
Вы можете использовать
useState
несколько раз в одном компоненте для управления разными частями состояния:
function MyComponent() {
const [count, setCount] = useState(0);
const [text, setText] = useState('');
return (
<div>
<p>Счетчик: {count}</p>
<button onClick={() => setCount(count + 1)}>Увеличить</button>
<input type="text" value={text} onChange={e => setText(e.target.value)} />
<p>Текст: {text}</p>
</div>
);
}
Когда использовать
useState
?* Для любого изменяемого значения, которое должно вызывать перерендер компонента при изменении.
* Для данных, специфичных для этого компонента.
Ключевые моменты:
*
useState
возвращает массив из двух элементов: текущее состояние и функцию для его обновления.* Обновление состояния асинхронно. React может группировать несколько обновлений для оптимизации.
* При обновлении объекта или массива всегда создавайте новую копию, а не мутируйте существующую.
Используйте эту шпаргалку, чтобы уверенно работать с состоянием в ваших React-приложениях!
👉 @frontend_1
👍4
🚀 Хотите стать экспертом в Angular? Пройдите тест и узнайте, готовы ли вы к нашему курсу!
Перед тем как погрузиться в мир Angular, проверьте свои знания JavaScript с помощью нашего вступительного теста. Это не только отличный способ оценить ваш уровень, но и первый шаг к освоению одного из самых востребованных фреймворков для веб-разработки. 🌍
Что вас ждёт на курсе Angular Developer?
- Создание SPA приложений с использованием лучших практик.
- Работа с TypeScript для создания чистого и поддерживаемого кода.
- Глубокие знания Angular для реальных проектов.
- Освоение реактивного программирования с помощью RxJS.
- Оптимизация производительности приложений.
👨💻 Для кого этот курс?
- JavaScript-разработчики, желающие углубить свои знания и освоить Angular.
- Backend-разработчики, стремящиеся стать Fullstack-разработчиками.
- Начинающие фронтендеры, готовые освоить строгий и структурированный фреймворк.
Что даст вам курс?
- Вы научитесь создавать высококачественные приложения с Angular.
- Освоите современные подходы в разработке с использованием TypeScript и RxJS.
- Станете уверенным в написании масштабируемого и легко поддерживаемого кода.
🔥 Проходите тест и узнайте свой уровень! Он поможет вам понять, насколько готовы к курсу, а также какие темы стоит освежить перед началом обучения.
Тест и подробнее о курсе Angular Developer - https://vk.cc/cNl3ym
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Перед тем как погрузиться в мир Angular, проверьте свои знания JavaScript с помощью нашего вступительного теста. Это не только отличный способ оценить ваш уровень, но и первый шаг к освоению одного из самых востребованных фреймворков для веб-разработки. 🌍
Что вас ждёт на курсе Angular Developer?
- Создание SPA приложений с использованием лучших практик.
- Работа с TypeScript для создания чистого и поддерживаемого кода.
- Глубокие знания Angular для реальных проектов.
- Освоение реактивного программирования с помощью RxJS.
- Оптимизация производительности приложений.
👨💻 Для кого этот курс?
- JavaScript-разработчики, желающие углубить свои знания и освоить Angular.
- Backend-разработчики, стремящиеся стать Fullstack-разработчиками.
- Начинающие фронтендеры, готовые освоить строгий и структурированный фреймворк.
Что даст вам курс?
- Вы научитесь создавать высококачественные приложения с Angular.
- Освоите современные подходы в разработке с использованием TypeScript и RxJS.
- Станете уверенным в написании масштабируемого и легко поддерживаемого кода.
🔥 Проходите тест и узнайте свой уровень! Он поможет вам понять, насколько готовы к курсу, а также какие темы стоит освежить перед началом обучения.
Тест и подробнее о курсе Angular Developer - https://vk.cc/cNl3ym
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Ошибки при работе с tailwindcss
Использование модификатора !important чтобы перебить другие классы (стили).
Использование !important в 99% не нужен. Только в крайних ситуациях, когда работаете со сторонними библиотеками и привычными способами не получается повысить силу селектора.
Плохой код:
Хороший:
https://habr.com/ru/articles/858426/
👉 @frontend_1
Использование модификатора !important чтобы перебить другие классы (стили).
Использование !important в 99% не нужен. Только в крайних ситуациях, когда работаете со сторонними библиотеками и привычными способами не получается повысить силу селектора.
Плохой код:
className={cn(
'bg-slate-100',{
'!bg-slate-200': isActive,
})}
Хороший:
className={cn('bg-slate-100', 'active:bg-slate-200')}
https://habr.com/ru/articles/858426/
👉 @frontend_1
👍2🤔1
HTML input types сильно различаются в зависимости от значения атрибута
Ознакомьтесь с этой шпаргалкой на будущее 🚀
👉 @frontend_1
type
, который вы используете 👨💻.Ознакомьтесь с этой шпаргалкой на будущее 🚀
👉 @frontend_1
👍6
🚀 Хотите стать Vue-разработчиком?
Пройдите вступительное тестирование и получите шанс обучаться на курсе Vue.js разработчик от OTUS! 🎓
Почему это важно?
- Знания для реальной работы: на курсе не просто теория, а практика на реальных проектах.
- Готовое портфолио: в конце обучения вы создаете полноценное приложение, которое можно показать работодателю.
- Поддержка экспертов: менторы из индустрии помогут на каждом шаге.
- Углубленное изучение Vue: от основ до продвинутых технологий — все, что нужно для успешной карьеры.
Как это работает?
1. Пройдите тестирование и оцените свой уровень.
2. Получите спеццену при поступлении в группу курса и начните обучение. Подробности уточняйте у менеджера.
3. Получайте знания, расширяйте свой стек технологий, реализуйте выпускной проект.
🔗 Пройти тестирование: https://vk.cc/cNl6Ia
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Пройдите вступительное тестирование и получите шанс обучаться на курсе Vue.js разработчик от OTUS! 🎓
Почему это важно?
- Знания для реальной работы: на курсе не просто теория, а практика на реальных проектах.
- Готовое портфолио: в конце обучения вы создаете полноценное приложение, которое можно показать работодателю.
- Поддержка экспертов: менторы из индустрии помогут на каждом шаге.
- Углубленное изучение Vue: от основ до продвинутых технологий — все, что нужно для успешной карьеры.
Как это работает?
1. Пройдите тестирование и оцените свой уровень.
2. Получите спеццену при поступлении в группу курса и начните обучение. Подробности уточняйте у менеджера.
3. Получайте знания, расширяйте свой стек технологий, реализуйте выпускной проект.
🔗 Пройти тестирование: https://vk.cc/cNl6Ia
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
🚀 Git для фронтендера: Осваиваем продвинутые команды!
Все мы знаем основы Git:
🌱 Ветки: Ваш личный песочник
Ветки – это как параллельные вселенные вашего кода. Они позволяют вам работать над новой фичей или исправлением бага, не затрагивая основной код (обычно ветку
Почему это важно?
🟢 Изоляция: Ваши изменения не сломают работу других разработчиков.
🟢 Безопасность: Можно экспериментировать, не боясь испортить стабильную версию.
🟢 Параллельная разработка: Несколько фич могут разрабатываться одновременно.
Основные команды для работы с ветками:
🟢
🟢
🟢
🟢
🟢
💥 Разрешение конфликтов: Не паникуем!
Конфликты слияния (merge conflicts) – это неизбежная часть командной разработки. Они возникают, когда Git не может автоматически объединить изменения из разных веток, потому что они затронули одну и ту же строку кода или файл.
Как это выглядит?
В файле появятся специальные маркеры:
Что делать?
1. Определите конфликтующие участки: Ищите маркеры
2. Примите решение: Вручную отредактируйте файл, оставив нужный код (ваш, чужой или комбинацию).
3. Удалите маркеры: Очень важно убрать все эти
4. Добавьте и закоммитьте изменения:
🟢
🟢
Спокойствие и внимание к деталям – залог успешного разрешения конфликтов!
✨ Git Rebase: Чистая история коммитов
Когда использовать
🟢 Для "очистки" вашей ветки перед мержем в
🟢 Чтобы синхронизировать свою ветку с
Пример использования:
1. Переключитесь на свою фича-ветку:
2. Заберите свежие изменения из
3. Выполните rebase:
Важно:
🟢 Никогда не делайте
🟢 При
👉 @frontend_1
Все мы знаем основы Git:
add
, commit
, push
. Но чтобы по-настоящему эффективно работать в команде и поддерживать чистую историю проекта, нужно копнуть глубже. Сегодня поговорим о трёх мощных инструментах, которые сделают вашу работу с Git намного комфортнее: ветки, разрешение конфликтов и rebase.🌱 Ветки: Ваш личный песочник
Ветки – это как параллельные вселенные вашего кода. Они позволяют вам работать над новой фичей или исправлением бага, не затрагивая основной код (обычно ветку
main
или master
).Почему это важно?
Основные команды для работы с ветками:
git branch <название_ветки>
: Создать новую ветку.git checkout <название_ветки>
: Переключиться на ветку.git checkout -b <название_ветки>
: Создать и сразу переключиться (комбинация двух предыдущих).git branch -d <название_ветки>
: Удалить ветку (после мержа).git merge <название_ветки>
: Влить изменения из указанной ветки в текущую.💥 Разрешение конфликтов: Не паникуем!
Конфликты слияния (merge conflicts) – это неизбежная часть командной разработки. Они возникают, когда Git не может автоматически объединить изменения из разных веток, потому что они затронули одну и ту же строку кода или файл.
Как это выглядит?
В файле появятся специальные маркеры:
<<<<<<< HEAD
Ваш код в текущей ветке
=======
Код из ветки, которую вы мержите
>>>>>>> feature/new-design
Что делать?
1. Определите конфликтующие участки: Ищите маркеры
<<<<<<<
, =======
, >>>>>>>
.2. Примите решение: Вручную отредактируйте файл, оставив нужный код (ваш, чужой или комбинацию).
3. Удалите маркеры: Очень важно убрать все эти
<<<<<<<
, =======
, >>>>>>>
!4. Добавьте и закоммитьте изменения:
git add <конфликтующий_файл>
git commit -m "Resolve merge conflict"
Спокойствие и внимание к деталям – залог успешного разрешения конфликтов!
✨ Git Rebase: Чистая история коммитов
git rebase
позволяет переписать историю коммитов, перемещая или комбинируя их. В отличие от merge
, который добавляет новый коммит слияния, rebase
"пересаживает" ваши коммиты на новый базовый коммит, создавая линейную и чистую историю.Когда использовать
rebase
?main
: Сделать историю более читаемой, сгруппировать мелкие коммиты.main
: Подтянуть свежие изменения из main
в свою фича-ветку без создания лишнего мерж-коммита.Пример использования:
1. Переключитесь на свою фича-ветку:
git checkout feature/my-new-feature
2. Заберите свежие изменения из
main
: git pull origin main
(или git fetch origin main
)3. Выполните rebase:
git rebase main
Важно:
rebase
публичных веток! Это может сломать историю для других разработчиков. Используйте rebase только для своих личных веток, которые ещё не были отправлены в общий репозиторий или над которыми вы работаете в одиночку.rebase
могут возникнуть конфликты, решать их нужно так же, как и при merge
.👉 @frontend_1
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6❤2
🥾 Первый шаг в Angular - создаем приложение с нуля
Вводное знакомство с Angular - современным фреймворком для разработки веб-приложений. Мы расскажем о его основных концепциях, структуре и возможностях.
👉 Какие ключевые темы и вопросы будут рассмотрены на вебинаре?
- Что такое Angular и зачем он нужен
- Основные компоненты Angular:Модули, компоненты, директивы, пайпы, сервисы
- Работа с данными: привязка данных (data binding)
- Основы маршрутизации (routing)
- Простая форма и валидация
- Как запустить и протестировать приложение
- Какие результаты и навыки получат участники после вебинара?
Бесплатный вебинар проходит в рамках курса “Angular Developer“
Регистрация и подробнее о курсе Angular Developer - https://vk.cc/cNmlMM
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Вводное знакомство с Angular - современным фреймворком для разработки веб-приложений. Мы расскажем о его основных концепциях, структуре и возможностях.
👉 Какие ключевые темы и вопросы будут рассмотрены на вебинаре?
- Что такое Angular и зачем он нужен
- Основные компоненты Angular:Модули, компоненты, директивы, пайпы, сервисы
- Работа с данными: привязка данных (data binding)
- Основы маршрутизации (routing)
- Простая форма и валидация
- Как запустить и протестировать приложение
- Какие результаты и навыки получат участники после вебинара?
Бесплатный вебинар проходит в рамках курса “Angular Developer“
Регистрация и подробнее о курсе Angular Developer - https://vk.cc/cNmlMM
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
📌Подборка полезных функций, которые пригодятся продвинутым frontend-разработчикам при работе с UI, производительностью и архитектурой
1. Throttle
Контролирует частоту вызова функции, полезно для scroll/resize-событий.
2. Debounce
Откладывает выполнение функции до окончания серии вызовов.
3. Deep Clone (без structuredClone)
4. Safe Access (Optional Chaining + Fallback)
5. Wait (async delay)
6. Generate UUID v4
7. Copy to Clipboard
8. Detect Outside Click (для dropdown/modals)
9. Download File from Blob
10. Dynamic Script Loader (например, для внешних SDK)
👉 @frontend_1
1. Throttle
Контролирует частоту вызова функции, полезно для scroll/resize-событий.
function throttle(fn: Function, delay: number) {
let last = 0;
return (...args: any[]) => {
const now = Date.now();
if (now - last >= delay) {
last = now;
fn(...args);
}
};
}
2. Debounce
Откладывает выполнение функции до окончания серии вызовов.
function debounce(fn: Function, delay: number) {
let timeout: ReturnType<typeof setTimeout>;
return (...args: any[]) => {
clearTimeout(timeout);
timeout = setTimeout(() => fn(...args), delay);
};
}
3. Deep Clone (без structuredClone)
function deepClone<T>(obj: T): T {
return JSON.parse(JSON.stringify(obj));
}
Подходит для простых объектов, не содержащих функций, дат и т.п.
4. Safe Access (Optional Chaining + Fallback)
function get<T>(obj: any, path: string, fallback?: T): T {
return path.split('.').reduce((acc, key) => acc?.[key], obj) ?? fallback;
}
5. Wait (async delay)
function wait(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms));
}
6. Generate UUID v4
function uuidv4() {
return crypto.randomUUID(); // нативно в современных браузерах
}
7. Copy to Clipboard
async function copyToClipboard(text: string) {
try {
await navigator.clipboard.writeText(text);
} catch {
const textarea = document.createElement('textarea');
textarea.value = text;
document.body.appendChild(textarea);
textarea.select();
document.execCommand('copy');
document.body.removeChild(textarea);
}
}
8. Detect Outside Click (для dropdown/modals)
function onClickOutside(element: HTMLElement, callback: () => void) {
function handler(event: MouseEvent) {
if (!element.contains(event.target as Node)) {
callback();
}
}
document.addEventListener('click', handler);
return () => document.removeEventListener('click', handler); // для очистки
}
9. Download File from Blob
function downloadBlob(blob: Blob, filename: string) {
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = filename;
a.click();
URL.revokeObjectURL(url);
}
10. Dynamic Script Loader (например, для внешних SDK)
function loadScript(src: string): Promise<void> {
return new Promise((resolve, reject) => {
const script = document.createElement('script');
script.src = src;
script.async = true;
script.onload = () => resolve();
script.onerror = () => reject(new Error(`Failed to load ${src}`));
document.head.appendChild(script);
});
}
👉 @frontend_1
👍10❤1
Как выжить в мире сложных интерфейсов в 2025-м: 7 работающих рецептов от React и CSS до дизайн-систем
Как говорил дядя Бен, большие продукты — это и большая ответственность. И без сложных интерфейсов тут никуда. А с ними и исследования становятся труднее, и встречается больше препятствий на этапе кода — от нюансов реактивного программирования до риска утонуть в разнообразии CSS-спецификаций.
Для МойОфис как мультипродуктовой экосистемы со сквозными сценариями — все эти вопросы очень актуальны! Поэтому на прошлой неделе JS-еры, дизайнеры и UX-исследователи нашей и других компаний собрались на митапе под названием Frontend&UX Talks, чтобы обсудить вопросы современного веба. Получилось интересно, драйвово и даже сказочно! (И я в прямом смысле этого слова :-))
В статье расскажем в 7 тезисах, к каким выводам пришли и как именно: поехали!
https://habr.com/ru/companies/ncloudtech/articles/924704/
👉 @frontend_1
Как говорил дядя Бен, большие продукты — это и большая ответственность. И без сложных интерфейсов тут никуда. А с ними и исследования становятся труднее, и встречается больше препятствий на этапе кода — от нюансов реактивного программирования до риска утонуть в разнообразии CSS-спецификаций.
Для МойОфис как мультипродуктовой экосистемы со сквозными сценариями — все эти вопросы очень актуальны! Поэтому на прошлой неделе JS-еры, дизайнеры и UX-исследователи нашей и других компаний собрались на митапе под названием Frontend&UX Talks, чтобы обсудить вопросы современного веба. Получилось интересно, драйвово и даже сказочно! (И я в прямом смысле этого слова :-))
В статье расскажем в 7 тезисах, к каким выводам пришли и как именно: поехали!
https://habr.com/ru/companies/ncloudtech/articles/924704/
👉 @frontend_1
👍5❤1
🚀 Упростите разработку с Vue: создаём игру за 1 вебинар
🔥Присоединяйтесь к открытому вебинару 16 июля в 20:00 мск., где мы покажем, как Vue упрощает разработку и делает её быстрее, чем привычный React.
На открытом уроке разберём:
🔹 как устроена реактивность во Vue через ref и в чём её отличие от useState в React;
🔹 управление логикой интерфейса с помощью v-if, v-model и событий;
🔹 как работать с таймерами, анимациями и рендерингом без сторонних библиотек;
🔹 пошаговое создание игры: от таймера и счёта до анимаций и рестарта;
🔹 почему Vue — это не только для новичков, а для тех, кто ценит чистоту, контроль и скорость разработки.
Не упустите шанс взглянуть на Vue в бою!
👉Регистрируйтесь: https://vk.cc/cNx7D9
Бесплатное занятие приурочено к старту курса “Vue.js разработчик”, на котором можно глубже погрузиться в особенности фреймворка, научиться работать с его инструментами и создавать реальные проекты.
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
🔥Присоединяйтесь к открытому вебинару 16 июля в 20:00 мск., где мы покажем, как Vue упрощает разработку и делает её быстрее, чем привычный React.
На открытом уроке разберём:
🔹 как устроена реактивность во Vue через ref и в чём её отличие от useState в React;
🔹 управление логикой интерфейса с помощью v-if, v-model и событий;
🔹 как работать с таймерами, анимациями и рендерингом без сторонних библиотек;
🔹 пошаговое создание игры: от таймера и счёта до анимаций и рестарта;
🔹 почему Vue — это не только для новичков, а для тех, кто ценит чистоту, контроль и скорость разработки.
Не упустите шанс взглянуть на Vue в бою!
👉Регистрируйтесь: https://vk.cc/cNx7D9
Бесплатное занятие приурочено к старту курса “Vue.js разработчик”, на котором можно глубже погрузиться в особенности фреймворка, научиться работать с его инструментами и создавать реальные проекты.
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
❤1