Функция setup в Go Golang

28 января 2026
Автор

Олег Марков

Введение

Функция setup в Go — это не встроенная конструкция языка, а распространённый паттерн. Её используют для подготовки окружения: инициализации зависимостей, конфигурации, временных ресурсов, моков и т.д. Чаще всего вы встретите функцию setup в тестах, но она полезна и в боевом коде, если нужно аккуратно собрать сложные объекты перед использованием.

Смотрите, я покажу вам, как на практике функция setup помогает:

  • Уменьшить дублирование кода.
  • Сделать тесты короче и понятнее.
  • Явно описать зависимости компонента.
  • Стандартизировать процесс инициализации приложения или подсистемы.

Давайте разберёмся, как устроен этот паттерн, какие варианты реализации бывают, где его стоит применять и как не перегнуть палку.

Что такое функция setup и зачем она нужна

Общая идея

Под функцией setup обычно понимают обычную Go-функцию, которая:

  • создаёт и настраивает нужные объекты;
  • возвращает эти объекты вызывающему коду;
  • иногда дополнительно возвращает функцию teardown (для очистки ресурсов).

Общий смысл: вы выносите повторяющуюся инициализацию в одно место. В тестах это особенно заметно, когда у каждого теста одна и та же подготовка данных, окружения или зависимостей.

Где обычно применяется setup

Чаще всего функция setup встречается в трёх контекстах:

  1. В модульных тестах:

    • поднятие моков и фейковых реализаций;
    • инициализация in-memory БД;
    • подготовка тестовых конфигураций.
  2. В интеграционных тестах:

    • создание временных каталогов и файлов;
    • запуск тестового HTTP-сервера;
    • подключение к тестовой БД или Docker-контейнеру.
  3. В приложении:

    • функция setup как часть инициализации приложения (например, в main);
    • построение зависимостей (DI без сторонних фреймворков);
    • выделенная setup-функция для каждого модуля (setupHTTP, setupDB и т.д.).

Давайте теперь посмотрим, как это выглядит в коде в разных сценариях.

Функция setup в модульных тестах

Базовый вариант setup в тесте

Один из самых частых кейсов — подготовка общего окружения для группы тестов. Пример:

package user_test

import (
    "testing"
)

// UserService - простая зависимость, которую нам нужно инициализировать
type UserService struct {
    repo UserRepository
}

// UserRepository - интерфейс репозитория пользователей
type UserRepository interface {
    Create(name string) error
}

// fakeUserRepo - фейковая реализация репозитория для тестов
type fakeUserRepo struct {
    created []string
}

func (f *fakeUserRepo) Create(name string) error {
    // Здесь мы просто сохраняем имя в памяти
    f.created = append(f.created, name)
    return nil
}

// setup - функция, которая готовит UserService и возвращает его
func setup() *UserService {
    // Инициализируем фейковый репозиторий
    repo := &fakeUserRepo{}

    // Собираем сервис с нужными зависимостями
    svc := &UserService{
        repo: repo,
    }

    // Возвращаем готовый сервис
    return svc
}

func TestUserCreate(t *testing.T) {
    // Вызываем setup один раз в начале теста
    svc := setup()

    // Дальше используем подготовленный сервис
    if err := svc.repo.Create("Alice"); err != nil {
        t.Fatalf("unexpected error: %v", err)
    }
}

Здесь функция setup:

  • инкапсулирует детали создания fakeUserRepo;
  • собирает UserService;
  • возвращает готовый объект для теста.

Это простой, но на практике очень распространённый шаблон.

Добавляем teardown (очистку)

Иногда одного setup мало: после теста нужно очистить ресурсы — закрыть соединения, удалить файлы, остановить сервер и т.д. В таких случаях удобно, чтобы setup возвращала не только подготовленные объекты, но и функцию teardown.

Давайте разберём пример с временным каталогом:

package files_test

import (
    "os"
    "path/filepath"
    "testing"
)

// setup - готовит временный каталог и возвращает путь и функцию очистки
func setup(t *testing.T) (string, func()) {
    // t.Helper помечает эту функцию как вспомогательную для теста
    t.Helper()

    // Создаём временную директорию
    dir, err := os.MkdirTemp("", "files_test_*")
    if err != nil {
        // Если setup не удалось, тест дальше нет смысла выполнять
        t.Fatalf("failed to create temp dir: %v", err)
    }

    // Возвращаем путь и функцию teardown
    teardown := func() {
        // Удаляем директорию рекурсивно
        _ = os.RemoveAll(dir)
    }

    return dir, teardown
}

func TestWriteFile(t *testing.T) {
    dir, teardown := setup(t)
    // Обязательно вызываем teardown в конце теста
    defer teardown()

    // Здесь мы создаём путь к файлу внутри временной директории
    filePath := filepath.Join(dir, "test.txt")

    // Записываем файл
    if err := os.WriteFile(filePath, []byte("hello"), 0o600); err != nil {
        t.Fatalf("write failed: %v", err)
    }
}

Обратите внимание:

  • setup принимает *testing.T, чтобы иметь возможность вызывать t.Helper и t.Fatalf;
  • teardown — замыкание, которое знает, что и где нужно удалить;
  • в тесте используется defer teardown(), чтобы гарантировать выполнение очистки.

Такой паттерн setup + teardown вы будете встречать очень часто.

Setup для группы тестов (table-driven tests)

Часто вы хотите использовать один и тот же setup для нескольких кейсов. Здесь удобно комбинировать setup с табличными тестами.

Давайте посмотрим на пример:

package math_test

import "testing"

// Calculator - простой тип для примера
type Calculator struct {
    base int
}

func (c *Calculator) Add(n int) int {
    // Складываем число с базовым значением
    return c.base + n
}

// setupCalculator - готовит калькулятор для тестов
func setupCalculator(t *testing.T) *Calculator {
    t.Helper()

    // Инициализируем калькулятор с базовым значением
    return &Calculator{base: 10}
}

func TestCalculator_Add(t *testing.T) {
    // Подготовка выполняется один раз в начале теста
    calc := setupCalculator(t)

    tests := []struct {
        name string
        in   int
        want int
    }{
        {"add positive", 5, 15},
        {"add zero", 0, 10},
        {"add negative", -3, 7},
    }

    for _, tt := range tests {
        // Запускаем под-тест
        t.Run(tt.name, func(t *testing.T) {
            // Здесь можно вызывать setup внутри каждого под-теста,
            // если нужно независимое состояние
            got := calc.Add(tt.in)
            if got != tt.want {
                t.Errorf("Add(%d) = %d, want %d", tt.in, got, tt.want)
            }
        })
    }
}

Смотрите, я специально вынес инициализацию калькулятора в отдельную setupCalculator, чтобы:

  • можно было легко менять базовое значение;
  • в других тестах использовать тот же способ инициализации;
  • уменьшить шум в теле самого теста.

Если бы калькулятор имел сложные зависимости, выгода была бы ещё более заметна.

Setup в интеграционных тестах

Подготовка HTTP-сервера

В интеграционных тестах очень часто приходится поднимать HTTP-сервер. Давайте создадим функцию setupServer, которая:

  • инициализирует роутер;
  • запускает тестовый HTTP-сервер;
  • возвращает URL и функцию остановки.
package api_test

import (
    "net/http"
    "net/http/httptest"
    "testing"
)

// setupServer - поднимает HTTP-сервер для тестов
func setupServer(t *testing.T) (*httptest.Server, string) {
    t.Helper()

    // Создаём обработчик для тестов
    handler := http.NewServeMux()

    // Регистрируем тестовый маршрут
    handler.HandleFunc("/ping", func(w http.ResponseWriter, r *http.Request) {
        // Отвечаем простым текстом
        _, _ = w.Write([]byte("pong"))
    })

    // Создаём тестовый сервер
    srv := httptest.NewServer(handler)

    // Возвращаем сервер и его URL
    return srv, srv.URL
}

func TestPing(t *testing.T) {
    srv, baseURL := setupServer(t)
    // Закрываем сервер после теста
    defer srv.Close()

    // Выполняем запрос к тестовому серверу
    resp, err := http.Get(baseURL + "/ping")
    if err != nil {
        t.Fatalf("request failed: %v", err)
    }
    defer resp.Body.Close()

    if resp.StatusCode != http.StatusOK {
        t.Fatalf("unexpected status: %d", resp.StatusCode)
    }
}

Как видите, этот код:

  • прекрасно демонстрирует роль setup как подготовщика окружения;
  • скрывает детали создания сервера;
  • делает тело теста коротким: только запрос и проверка результата.

Setup с подключением к БД

Сейчас покажу вам ещё один пример — когда setup берёт на себя подготовку соединения с БД. Для простоты рассмотрим in-memory SQLite (через modernc.org/sqlite или любую другую реализацию), но шаблон тот же и для PostgreSQL, MySQL и т.д.

package storage_test

import (
    "database/sql"
    "testing"

    _ "modernc.org/sqlite" // Подключаем драйвер SQLite
)

// setupDB - готовит соединение с тестовой базой
func setupDB(t *testing.T) (*sql.DB, func()) {
    t.Helper()

    // Создаём in-memory базу SQLite
    db, err := sql.Open("sqlite", ":memory:")
    if err != nil {
        t.Fatalf("failed to open db: %v", err)
    }

    // Настраиваем соединение (лимиты, опции)
    db.SetMaxOpenConns(1)

    // Создаём таблицу для тестов
    _, err = db.Exec(`CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)`)
    if err != nil {
        t.Fatalf("failed to create table: %v", err)
    }

    // Функция очистки
    teardown := func() {
        // Закрываем соединение
        _ = db.Close()
    }

    return db, teardown
}

func TestInsertUser(t *testing.T) {
    db, teardown := setupDB(t)
    defer teardown()

    // Вставляем данные для проверки
    _, err := db.Exec(`INSERT INTO users (name) VALUES (?)`, "Alice")
    if err != nil {
        t.Fatalf("insert failed: %v", err)
    }

    // Проверяем, что запись появилась
    var count int
    if err := db.QueryRow(`SELECT COUNT(*) FROM users`).Scan(&count); err != nil {
        t.Fatalf("select failed: %v", err)
    }

    if count != 1 {
        t.Fatalf("unexpected row count: %d", count)
    }
}

Здесь функция setupDB:

  • создаёт соединение с БД;
  • создаёт схему (таблицу);
  • возвращает db и teardown.

Такую функцию можно многократно переиспользовать в разных тестах, не повторяя одно и то же.

Setup в боевом коде приложения

Setup как часть инициализации в main

Функция setup полезна не только в тестах. Очень часто её используют в пакете main для подготовки всех зависимостей приложения.

Смотрите пример небольшого HTTP-сервиса:

package main

import (
    "database/sql"
    "log"
    "net/http"
    "os"

    _ "github.com/lib/pq" // Драйвер PostgreSQL
)

// App - структура, описывающая наше приложение
type App struct {
    DB     *sql.DB
    Logger *log.Logger
    Mux    *http.ServeMux
}

// setup - готовит экземпляр приложения
func setup() (*App, error) {
    // Читаем конфигурацию из переменных окружения
    dsn := os.Getenv("DB_DSN")
    if dsn == "" {
        // Возвращаем ошибку, если конфигурации нет
        return nil, ErrMissingDSN
    }

    // Подключаемся к базе
    db, err := sql.Open("postgres", dsn)
    if err != nil {
        return nil, err
    }

    // Проверяем подключение
    if err := db.Ping(); err != nil {
        return nil, err
    }

    // Настраиваем логгер
    logger := log.New(os.Stdout, "app ", log.LstdFlags)

    // Создаём роутер
    mux := http.NewServeMux()

    // Регистрируем обработчики
    mux.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
        // Возвращаем простой статус
        w.WriteHeader(http.StatusOK)
        _, _ = w.Write([]byte("ok"))
    })

    // Собираем приложение
    app := &App{
        DB:     db,
        Logger: logger,
        Mux:    mux,
    }

    // Возвращаем готовое приложение
    return app, nil
}

// ErrMissingDSN - ошибка отсутствия DSN
var ErrMissingDSN = fmt.Errorf("DB_DSN is required")

func main() {
    app, err := setup()
    if err != nil {
        log.Fatalf("setup failed: %v", err)
    }

    // Запускаем HTTP-сервер
    if err := http.ListenAndServe(":8080", app.Mux); err != nil {
        log.Fatalf("server failed: %v", err)
    }
}

Покажу вам, почему такой подход удобен:

  • настройка зависимостей изолирована от функции main;
  • функцию setup можно переиспользовать в тестах (создавать приложение без запуска сервера);
  • код main остаётся очень простым и читаемым.

Setup на уровне модуля

Когда проект растёт, бывает полезно иметь несколько отдельных setup-функций:

  • setupLogger
  • setupDB
  • setupHTTP
  • setupConfig

Давайте посмотрим, как можно разбить инициализацию на несколько функций, а затем собрать всё в одну:

package main

import (
    "database/sql"
    "log"
    "net/http"
    "os"
)

// setupLogger - настраивает логгер
func setupLogger() *log.Logger {
    // Создаём логгер, который пишет в stdout
    return log.New(os.Stdout, "app ", log.LstdFlags|log.Lshortfile)
}

// setupDB - настраивает подключение к базе
func setupDB(logger *log.Logger) (*sql.DB, error) {
    dsn := os.Getenv("DB_DSN")
    if dsn == "" {
        // Логируем проблему конфигурации
        logger.Println("DB_DSN is empty")
        return nil, ErrMissingDSN
    }

    db, err := sql.Open("postgres", dsn)
    if err != nil {
        return nil, err
    }

    if err := db.Ping(); err != nil {
        return nil, err
    }

    return db, nil
}

// setupHTTP - готовит HTTP-маршруты
func setupHTTP(db *sql.DB, logger *log.Logger) *http.ServeMux {
    mux := http.NewServeMux()

    // Пример обработчика, использующего db и logger
    mux.HandleFunc("/users", func(w http.ResponseWriter, r *http.Request) {
        // Здесь можно работать с базой данных и логгером
        logger.Println("handle /users")
        w.WriteHeader(http.StatusOK)
        _, _ = w.Write([]byte("users list"))
    })

    return mux
}

// setupApp - собирает всё воедино
func setupApp() (*http.ServeMux, error) {
    // Сначала настраиваем логгер
    logger := setupLogger()

    // Затем настраиваем базу
    db, err := setupDB(logger)
    if err != nil {
        return nil, err
    }

    // И в конце настраиваем HTTP
    mux := setupHTTP(db, logger)

    return mux, nil
}

Давайте посмотрим, что даёт такой разнос:

  • каждая setup-функция отвечает за свою подсистему;
  • зависимости передаются явно (logger → db → http);
  • вы легко можете протестировать каждую setup-функцию отдельно.

Таким образом, слово setup в названиях хорошо передаёт идею: “здесь происходит подготовка и конфигурация”.

Паттерны реализации функции setup

Вариант 1. Возврат значения или структуры

Это самый простой и распространённый вариант: setup возвращает один объект или структуру со всеми нужными зависимостями.

Пример: структура TestEnv для тестов.

package service_test

import (
    "log"
    "testing"
)

// TestEnv - окружение для тестов
type TestEnv struct {
    Logger *log.Logger
    // Здесь могут быть другие поля - моки, фейки и т.д.
}

// setupEnv - создаёт и настраивает окружение для тестов
func setupEnv(t *testing.T) *TestEnv {
    t.Helper()

    logger := log.New(testWriter{t}, "test ", log.LstdFlags)

    return &TestEnv{
        Logger: logger,
    }
}

// testWriter - адаптер, пишущий в лог теста
type testWriter struct {
    t *testing.T
}

func (w testWriter) Write(p []byte) (int, error) {
    // Пишем в лог теста
    w.t.Logf("%s", p)
    return len(p), nil
}

Такой паттерн особенно удобен, если у вас много зависимостей, и вы хотите всё держать в одной структуре.

Вариант 2. Возврат значения + teardown

Мы уже смотрели такой вариант в тестах. Он особенно полезен, когда:

  • вы создаёте ресурсы, требующие освобождения;
  • вам нужна гарантия, что очистка выполнится в конце теста или функции.

Форма сигнатуры обычно такая:

func setupSomething(t *testing.T) (*Something, func()) {
    // Настраиваем ресурс
    // ...
    return obj, func() {
        // Очищаем ресурс
        // ...
    }
}

Здесь важно не забывать вызывать teardown:

obj, teardown := setupSomething(t)
defer teardown()

Вариант 3. Setup как метод на структуре

Иногда удобно сделать setup методом на типе, особенно если вы работаете с тестовыми фикстурами.

type TestFixture struct {
    DB *sql.DB
    // другие поля
}

// Setup - метод, который готовит фикстуру
func (f *TestFixture) Setup(t *testing.T) {
    t.Helper()

    // Инициализируем DB и другие поля
    // ...
}

// Teardown - метод очистки
func (f *TestFixture) Teardown() {
    // Закрываем ресурсы
    // ...
}

func TestSomething(t *testing.T) {
    var fx TestFixture

    fx.Setup(t)
    defer fx.Teardown()

    // Используем fx.DB и другие поля
}

Такой подход хорошо подходит, если у тестов много общего окружения и вы хотите сгруппировать его в один тип.

Рекомендации по дизайну функции setup

Делайте setup максимально явной

Полезно, чтобы функция setup:

  • принимала все необходимые параметры явно;
  • не прятала важную логику в глобальные переменные;
  • не изменяла глобальное состояние без крайней необходимости.

Например, вместо:

var globalDB *sql.DB

func setup() {
    // Плохо - записываем в глобальную переменную
    globalDB = createDB()
}

лучше:

func setupDB() *sql.DB {
    // Хорошо - возвращаем значение вызывающему коду
    return createDB()
}

Так вам будет проще тестировать код и понимать, откуда и куда текут зависимости.

Не перегружайте одну setup-функцию всем подряд

Если вы чувствуете, что в setup появилась логика, которая:

  • сама по себе сложная;
  • содержит условия, циклы, ветвления;
  • начинает обрабатывать много разных сценариев,

то стоит вынести часть кода в отдельные функции или типы.

Например, вместо одной огромной setup, которая инициализирует БД, кеш, HTTP, конфиг и очередь, лучше сделать:

  • setupConfig
  • setupLogger
  • setupDB
  • setupCache
  • setupHTTP
  • setupQueue

А затем собрать всё в одной функции, которая вызывает их по очереди.

Используйте t.Helper в тестовых setup

Когда вы пишете setup для тестов, почти всегда стоит вызывать t.Helper() в начале:

func setupSomething(t *testing.T) *Something {
    t.Helper()
    // дальше обычная логика
}

Это помогает при отладке: стек вызовов в ошибках будет указывать на строку в самом тесте, а не в функции setup.

Следите за временем работы setup

Иногда setup может занимать значительное время (например, запуск Docker-контейнера или миграций БД). В тестах это особенно критично.

Несколько практичных советов:

  • По возможности используйте ленивую инициализацию (один setup на пакет, а не на каждый тест).
  • Воспользуйтесь TestMain, если нужно настроить окружение один раз перед всем пакетом тестов.
  • Для тяжёлых интеграционных тестов заведите отдельный пакет или тег сборки, чтобы не замедлять быстрые модульные тесты.

Распространённые ошибки при использовании setup

Скрытые глобальные зависимости

Проблема: setup записывает данные в глобальные переменные, а тесты не изолированы друг от друга.

Пример проблемы:

var db *sql.DB

func setup(t *testing.T) {
    t.Helper()
    // Переоткрываем глобальную переменную
    db = createTestDB()
}

Разные тесты могут менять одно и то же глобальное состояние, и вы получите нестабильные, “мигающие” тесты.

Лучше:

func setup(t *testing.T) *sql.DB {
    t.Helper()
    return createTestDB()
}

Так вы явно передаёте db туда, где она нужна.

Отсутствие teardown там, где он нужен

Если setup создаёт внешние ресурсы (каталоги, файлы, соединения, серверы), но вы забываете их закрыть, то:

  • тесты могут “протекать” (оставлять мусор);
  • в CI могут кончиться дескрипторы файлов или портов;
  • локальная машина со временем зарастёт временными файлами.

Всегда, когда вы видите в setup создание чего-то внешнего, задавайте себе вопрос: нужна ли для этого teardown?

Слишком умный setup

Иногда setup пытается угадывать, что от него хотят, и делает слишком много:

  • загружает конфиг из 3 разных мест;
  • меняет поведение в зависимости от переменных окружения;
  • использует флаги командной строки.

Для тестов такой “умный” setup может быть проблемой — вы теряете предсказуемость и контроль. Лучше, чтобы setup был детерминированным и предсказуемым, а всё, что может меняться, передавалось ему явно параметрами.

Смешивание тестовой и боевой логики в одном setup

Ещё одна частая ошибка — использовать одну и ту же функцию setup и для продового кода, и для тестов, при этом внутри делать условия типа “если тест, то вот это, если прод, то другое”.

Например:

func setup() *App {
    if isTestEnv() {
        // используем in-memory базу
    } else {
        // подключаемся к настоящей базе
    }
}

Лучше разделять:

  • setupProdApp
  • setupTestApp

или иметь конструктор, который принимает интерфейсы/фабрики зависимостей, а уже в тестах и в проде вы передаёте разные реализации.

Заключение

Функция setup в Go — это паттерн, а не встроенный механизм языка. Именно поэтому у вас есть свобода выбирать форму и уровень абстракции, который лучше всего подходит вашему проекту и конкретной задаче.

Подведём основные выводы:

  • setup — это обычная функция, которая готовит окружение: объекты, ресурсы, конфигурацию;
  • особенно полезна в тестах, где помогает убрать дублирование и сделать код понятнее;
  • в боевом коде setup улучшает структуру инициализации, делает зависимостей явными;
  • сочетание setup + teardown — удобный паттерн для ресурсов, требующих очистки;
  • важно следить за тем, чтобы setup была:
    • предсказуемой;
    • явной по зависимостям;
    • не слишком перегруженной логикой;
    • аккуратно работала с глобальным состоянием.

Теперь, когда вы знаете, как устроена функция setup, вы можете осознанно использовать её в тестах и приложениях, строя более понятную и поддерживаемую архитектуру.

Частозадаваемые технические вопросы по теме статьи и ответы на них

Как сделать один общий setup для всего пакета тестов, а не вызывать его в каждом тесте?

Для этого используйте TestMain:

func TestMain(m *testing.M) {
    // Здесь вы делаете общий setup - БД, конфиг, внешние сервисы
    code := m.Run() // Запуск всех тестов пакета
    // Здесь можно сделать общий teardown
    os.Exit(code)
}

Если нужны значения из setup, сохраните их в пакетных переменных и используйте в тестах.

Как передавать t *testing.T в setup, если функция вызывается не напрямую из теста, а глубже?

Просто прокидывайте t по стеку вызовов:

func TestSomething(t *testing.T) {
    env := buildEnv(t)
    // ...
}

func buildEnv(t *testing.T) *Env {
    t.Helper()
    return setupEnv(t)
}

Важно, чтобы самая верхняя функция, которая владеет тестом, принимала *testing.T и передавала его дальше.

Можно ли использовать setup в бенчмарках и как это сделать правильно?

Да, но учитывайте, что код внутри цикла b.N должен измеряться, а setup — нет. Делайте подготовку до цикла:

func BenchmarkSomething(b *testing.B) {
    env := setupEnvForBench(b)

    b.ResetTimer() // Сбрасываем таймер, чтобы не учитывать setup

    for i := 0; i < b.N; i++ {
        // Здесь замеряется производительность
        doWork(env)
    }
}

Если нужен teardown, вызовите его после цикла.

Как протестировать саму функцию setup?

Относитесь к setup как к обычной функции. Пишите тесты, которые вызывают её и проверяют результат:

func TestSetupApp(t *testing.T) {
    app, err := setupApp()
    if err != nil {
        t.Fatalf("setupApp failed: %v", err)
    }
    if app.DB == nil {
        t.Fatalf("DB is nil after setup")
    }
}

Если setup сложная, имеет смысл разбить её на более мелкие функции и тестировать их отдельно.

Как быть, если setup зависит от переменных окружения, а их нужно менять в разных тестах?

Меняйте переменные окружения в самом тесте перед вызовом setup и очищайте после:

func TestWithCustomEnv(t *testing.T) {
    t.Setenv("DB_DSN", "test-dsn") // Go 1.17+
    app, err := setupApp()
    if err != nil {
        t.Fatalf("setupApp failed: %v", err)
    }
    // Дальше работайте с app
}

t.Setenv автоматически вернёт значение переменной в исходное состояние по окончании теста, что удобно и безопасно.

Стрелочка влевоWatch и WatchEffect в Vue 3 - подробный разбор с примерамиRef и Reactive в Vue 3 - понятное и подробное объяснениеСтрелочка вправо

Постройте личный план изучения Vue до уровня Middle — бесплатно!

Vue — часть карты развития Frontend

  • step100+ шагов развития
  • lessons30 бесплатных лекций
  • lessons300 бонусных рублей на счет

Бесплатные лекции

Все гайды по Vue

Руководство по валидации форм во Vue.jsИнтеграция Tiptap для создания редакторов на VueРабота с таблицами во Vue через TanStackИнструкция по установке и компонентам Vue sliderУправление пакетами Vue js с помощью npmУправление пакетами и node modules в Vue проектахКак использовать meta для улучшения SEO на VueПолный гайд по компоненту messages во Vuejs5 правил использования Inertia с Vue и LaravelРабота с модулями и пакетами в VueИнструкция по работе с grid на VueGithub для Vue проектов - подробная инструкция по хранению и совместной работеНастройка ESLint для Vue проектов и поддержка качества кодаОбработка ошибок и отладка в Vue.jsИспользование Vue Devtools для отладки и мониторинга приложенийРабота с конфигурационными файлами и скриптами VueСоздание и настройка проектов Vue с помощью Vue CLI3 способа интеграции Chart.js с Vue для создания графиковРабота с Canvas во VueИнструкция по реализации календаря во VueРабота с Ant Design Vue для создания UI на Vue
Vuex - полное руководство по управлению состоянием во Vue приложенияхРеактивные ссылки ref - полный разбор для разработчиковРеактивные объекты reactive-objects - подробное руководство с примерамиРеактивные переменные - концепция reactive и практические примерыМеханизм Provide Inject - как он работает и когда применятьPinia современный менеджер состояния для VueЛокальное состояние local state в веб разработкеГлобальное состояние в приложениях - global state
Обзор и использование утилит Vue для удобной разработкиРабота с обновлениями компонента и жизненным циклом updateРазрешение конфликтов и ошибок с помощью Vue resolveИспользование query-параметров и их обработка в маршрутах VueЗагрузка и управление состоянием загрузки в VueИспользование библиотек Vue для расширения функционалаРабота с JSON данными в приложениях VueКак работать с экземплярами компонента Instance во VueПолучение данных и API-запросы во Vue.jsЭкспорт и импорт данных и компонентов в VueОбработка событий и их передача между компонентами VuejsГайд по defineEmits на Vue 3Понимание core функционала Vue и его применениеПонимание и применение Composition API в Vue 3Понимание и работа с компилятором VueКогда и как использовать $emit и call во VueВзаимодействие с внешними API через Axios в Vue
Веб приложения на Vue архитектура и лучшие практикиИспользование Vite для быстрого старта и сборки проектов на Vue 3Работа с URL и ссылками в приложениях на VueРабота с пользовательскими интерфейсами и UI библиотеками во VueОрганизация и структура исходных файлов в проектах VueИспользование Quasar Framework для разработки на Vue с готовыми UI-компонентамиОбзор популярных шаблонов и стартовых проектов на VueИнтеграция Vue с PHP для создания динамичных веб-приложенийКак организовать страницы и маршруты в проекте на VueNuxt JS и Vue 3 для SSR приложенийСоздание серверных приложений на Vue с помощью Nuxt jsИспользование Vue Native для разработки мобильных приложенийОрганизация и управление индексной страницей в проектах VueИспользование Docker для контейнеризации приложений на VueИнтеграция Vue.js с Django для создания полноценных веб-приложенийСоздание и работа с дистрибутивом build dist Vue приложенийРабота со стилями и CSS в Vue js для красивых интерфейсовСоздание и структурирование Vue.js приложенияКак исправить ошибку cannot find module vueНастройка и сборка проектов Vue с использованием современных инструментовИнтеграция Vue с Bitrix для корпоративных решенийРазработка административных панелей на Vue js
Функция append в Go GolangОтображение компонента mounted - практическое руководствоХуки жизненного цикла компонентов - полное руководство для разработчиковУничтожение компонента destroyed - как правильно очищать ресурсы и подпискиИнициализация данных в состоянии created - как и когда подготавливать данные в приложенииОбновление компонента beforeUpdate во VueМонтирование компонента - хук beforeMount в VueРазрушение компонента во Vue - beforeDestroy и beforeUnmountСоздание экземпляра beforeCreate - полный разбор жизненного цикла
5 библиотек для создания tree view во VueИнтеграция Tailwind CSS с Vue для современных интерфейсовИнтеграция Vue с серверной частью и HTTPS настройкамиКак обрабатывать async операции с Promise во VueИнтеграция Node.js и Vue.js для разработки приложенийРуководство по интеграции Vue js в NET проектыПримеры использования JSX во VueГайд по импорту и регистрации компонентов на VueМногоязычные приложения на Vue с i18nИнтеграция FLIR данных с Vue5 примеров использования filter во Vue для упрощения разработки3 примера реализации drag-and-drop во Vue
Слоты компонента - концепция и практическое использованиеРегистрация компонентов component-registration в приложениях с внедрением зависимостейProps компонента в React - полный разбор с примерамиФункциональные компоненты в React - функциональный подход к построению интерфейсовСобытия компонента - events в современных интерфейсахДинамические компоненты - dynamic-componentsСоздание компонента component - практическое руководствоАсинхронные компоненты async-components - практическое руководство
Наблюдатели watchers - от паттерна до практических реализацийУправление переменными и реактивными свойствами во VueИспользование v for и slot в VueПрименение v-bind для динамической привязки атрибутов в VueУправление пользователями и их данными в Vue приложенияхСоздание и использование UI Kit для Vue приложенийТипизация и использование TypeScript в VuejsШаблоны Vue templates - практическое руководство для разработчиковИспользование шаблонов в Vue js для построения интерфейсовИспользование Swiper для создания слайдеров в VueРабота со стилями и стилизацией в VueСтруктура и особенности Single File Components SFC в VueРабота со SCSS в проектах на Vue для стилизацииРабота со скроллингом и прокруткой в Vue приложенияхПрименение script setup синтаксиса в Vue 3 для упрощения компонентовИспользование scoped стилей для изоляции CSS в компонентах Vue3 способа улучшить навигацию Vue с push()Обработка запросов и асинхронных операций в VueРеактивность Vue reactivity - как это работает под капотом и как этим пользоватьсяПонимание и использование provide inject для передачи данных между компонентамиПередача и использование props в Vue 3 для взаимодействия компонентовПередача данных между компонентами с помощью props в Vue jsУправление property и функциями во Vue.jsРабота со свойствами компонентов VueУправление параметрами и динамическими данными во VueОпции компонента в Go - паттерн component-optionsРабота с lifecycle-хуком onMounted во VueОсновы работы с объектами в VueПонимание жизненного цикла компонента Vue js на примере mountedИспользование модальных окон modal в Vue приложенияхИспользование методов в компонентах Vue для обработки логикиИспользование метода map в Vue для обработки массивовИспользование хуков жизненного цикла Vue для управления состоянием компонентаРабота с ключами key в списках и компонентах VueОбработка пользовательского ввода в Vue.jsРабота с изображениями и их оптимизация в VueИспользование хуков жизненного цикла в VueОрганизация сеток и гридов для верстки интерфейсов на VueСоздание и управление формами в VueОрганизация файлов и структура проекта Vue.jsКомпоненты Vue создание передача данных события и emit3 способа манипулирования DOM на VueРабота с динамическими компонентами и данными в VueРуководство по div во VueИспользование директив в Vue и их расширенные возможностиОсновы и применение директив в VueИспользование директив и их особенности на Vue с помощью defineИспользование компонентов datepicker в Vue для выбора датОрганизация циклов и итераций во VueКак работает компиляция Vue CoreВычисляемые свойства computed во Vue.jsСоздание и использование компонентов в Vue JSОбработка кликов и пользовательских событий в VueИспользование классов в Vue для организации кода и компонентовИспользование директивы checked для управления состоянием чекбоксов в VueГайд на checkbox компонент во VueОтображение данных в виде графиков с помощью Vue ChartСоздание и настройка кнопок в VueСоздание и настройка кнопок в Vue приложенияхРабота с lifecycle-хуками beforeCreate и beforeMount во VueОсновы Vue - vue-basics для уверенного стартаИспользование массивов и методов их обработки в VueИспользование массивов и их обработка в Vue
Использование Vuetify для создания современных интерфейсов на VueИспользование transition во VueТестирование компонентов и приложений на VueТелепортация - архитектура и реализация в серверных приложенияхРабота с teleport для управления DOM во VueSuspense в React - управление асинхронными данными и ленивой загрузкойПять шагов по настройке SSR в VuejsИспользование Shadcn UI компонентов с Vue для продвинутых интерфейсовИспользование router-link для навигации в Vue RouterКак использовать require в Vue для динамического импорта модулейРабота с динамическим рендерингом и виртуальным DOM на Vue.jsИспользование ref для управления ссылками и реактивностью в Vue 3Использование Vue Pro и его преимущества для профессиональной разработкиПлагины Vue vue-plugins - полное практическое руководствоРуководство по nextTick для работы с DOMМиксины - mixins в современном программированииJSX в Vue с использованием плагина vue-jsxСоздание и использование компонентов с помощью Vue js и CУправление состоянием и реактивностью через inject и provideДинамическое обновление компонентов и данных на VueГлубокое изучение документации Vue и как эффективно её использоватьКастомные элементы - Custom Elements в современном JavaScriptИспользование Crystal с Vue для разработкиИспользование вычисляемых свойств для динамического отображения данных на Vue jsОптимизация производительности и предупреждения в Vue
Открыть базу знаний

Лучшие курсы по теме

изображение курса

Vue 3 и Pinia

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.9
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

TypeScript с нуля

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.8
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Next.js - с нуля

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее

Отправить комментарий