0Pricing
C# Academy · Урок

Модель компонентов Blazor

Создавайте компоненты Razor, разбирайтесь в жизненном цикле компонентов и используйте параметры и каскадные значения.

«Модель компонентов Blazor» — бесплатный урок C# Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C# Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C# Academy содержит 4 уроков всего.

Что такое Blazor?

Blazor позволяет создавать интерактивные веб-интерфейсы с помощью C# вместо JavaScript. Компоненты определяются в файлах .razor, объединяющих разметку HTML и логику C#. Blazor работает на сервере (Blazor Server) или в браузере через WebAssembly (Blazor WASM).

Ваш первый компонент

Компонент Razor — это файл .razor с разметкой HTML и блоком @code для C#. Имя компонента становится именем HTML-тега.

@* Greeting.razor *@
<h2>Hello, @Name!</h2>
<p>You have @Count messages.</p>

@code {
    [Parameter] public string Name { get; set; } = "World";
    private int Count = 5;
}

Жизненный цикл компонента

У компонентов Blazor есть жизненный цикл с точками расширения, которые можно переопределять. Наиболее распространённые из них — OnInitializedAsync (загрузка данных) и OnParametersSetAsync (реакция на изменение параметров).

@code {
    private List<Product> Products = new();

    protected override async Task OnInitializedAsync()
    {
        // Called once on first render
        Products = await Http.GetFromJsonAsync<List<Product>>("/api/products")
                   ?? new();
    }

    protected override async Task OnParametersSetAsync()
    {
        // Called whenever parameters change
        await LoadDataAsync();
    }
}

Параметры: передача данных компонентам

Пометьте свойства атрибутом [Parameter], чтобы принимать данные от родительских компонентов. Параметры задаются до отображения и при изменении могут вызвать повторное отображение.

@* ProductCard.razor *@
<div class="card">
    <h4>@Product.Name</h4>
    <p>Price: @Product.Price.ToString("C")</p>
    <button @onclick="AddToCart">Add to Cart</button>
</div>

@code {
    [Parameter, EditorRequired]
    public Product Product { get; set; } = default!;

    [Parameter]
    public EventCallback<Product> OnAddToCart { get; set; }

    private async Task AddToCart() =>
        await OnAddToCart.InvokeAsync(Product);
}

Каскадные параметры

Каскадные параметры передаются вниз по дереву компонентов без явной передачи через каждый промежуточный уровень — это удобно для тем, информации о пользователе и общего состояния.

@* App.razor — wraps the whole app *@
<CascadingValue Value="CurrentUser">
    <Router AppAssembly="@typeof(App).Assembly">
        <Found Context="routeData">
            <RouteView RouteData="routeData" DefaultLayout="@typeof(MainLayout)" />
        </Found>
    </Router>
</CascadingValue>

@* Anywhere in the tree: *@
@code {
    [CascadingParameter]
    public UserInfo CurrentUser { get; set; } = default!;
}

Отображение списков и условных блоков

Используйте директивы Razor @if, @foreach и @for для отображения динамического содержимого. Всегда задавайте @key для элементов списка, чтобы эффективно вычислять различия.

@if (Products.Count == 0)
{
    <p>No products found.</p>
}
else
{
    <ul>
        @foreach (var product in Products)
        {
            <li @key="product.Id">
                <ProductCard Product="product" OnAddToCart="HandleAdd" />
            </li>
        }
    </ul>
}

RenderFragment и ChildContent

Используйте RenderFragment, чтобы передавать разметку как параметр — подобно слотам во Vue или дочерним элементам в React. Традиционное имя параметра — ChildContent.

@* Panel.razor *@
<div class="panel">
    <div class="panel-header">@Title</div>
    <div class="panel-body">@ChildContent</div>
</div>

@code {
    [Parameter] public string Title { get; set; } = "";
    [Parameter] public RenderFragment? ChildContent { get; set; }
}

@* Usage: *@
<Panel Title="Order Details">
    <p>Order #42 — Shipped</p>
</Panel>

Ссылки на компоненты с помощью @ref

Сохраните ссылку на дочерний компонент с помощью @ref, чтобы вызывать его общедоступные методы или читать его свойства из родительского компонента.

@* Parent.razor *@
<ConfirmDialog @ref="_dialog" OnConfirm="DeleteOrder" />
<button @onclick="() => _dialog!.Show()">Delete Order</button>

@code {
    private ConfirmDialog? _dialog;

    private async Task DeleteOrder()
    {
        await OrderService.DeleteAsync(CurrentOrderId);
        // Refresh UI...
    }
}

StateHasChanged и ручное повторное отображение

Blazor автоматически повторно отображает компонент после обработчиков событий. Для асинхронных изменений состояния за пределами обработчиков событий, например при срабатывании фонового таймера, вручную вызовите StateHasChanged().

@implements IDisposable

<p>Time: @CurrentTime</p>

@code {
    private string CurrentTime = "";
    private Timer? _timer;

    protected override void OnInitialized()
    {
        _timer = new Timer(_ =>
        {
            CurrentTime = DateTime.Now.ToString("HH:mm:ss");
            InvokeAsync(StateHasChanged); // thread-safe re-render
        }, null, 0, 1000);
    }

    public void Dispose() => _timer?.Dispose();
}

ShouldRender для повышения производительности

Переопределите ShouldRender(), чтобы пропускать ненужное повторное отображение. Возвращайте false, когда результат работы компонента не изменится, чтобы уменьшить накладные расходы на вычисление различий.

@code {
    private string _lastRenderedStatus = "";

    [Parameter] public string Status { get; set; } = "";

    protected override bool ShouldRender()
    {
        // Only re-render if Status actually changed
        if (Status == _lastRenderedStatus) return false;
        _lastRenderedStatus = Status;
        return true;
    }
}

Практический пример: компонент списка продуктов

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

@inject HttpClient Http

@if (_loading)
{
    <p>Loading products...</p>
}
else
{
    @foreach (var p in _products)
    {
        <ProductCard Product="p" OnAddToCart="AddToCart" />
    }
}

@code {
    private List<Product> _products = new();
    private bool _loading = true;

    [Parameter] public EventCallback<Product> OnCartUpdated { get; set; }

    protected override async Task OnInitializedAsync()
    {
        _products = await Http.GetFromJsonAsync<List<Product>>("/api/products")
                   ?? new();
        _loading = false;
    }

    private async Task AddToCart(Product p) => await OnCartUpdated.InvokeAsync(p);
}

Быстрая проверка

Какой метод жизненного цикла лучше всего подходит для загрузки данных из API при инициализации компонента Blazor?

Итоги: модель компонентов Blazor

Главные выводы:

  • Файлы .razor объединяют разметку HTML с C# в блоке @code
  • [Parameter] принимает данные от родителя; EventCallback передаёт события вверх
  • CascadingParameter передаёт данные вниз без последовательной передачи свойств через все уровни
  • RenderFragment/ChildContent позволяет создавать составные компоненты на основе слотов
  • OnInitializedAsync используется для первоначальной загрузки данных; StateHasChanged — для ручного повторного отображения
  • ShouldRender() пропускает ненужное вычисление различий для повышения производительности

Часто задаваемые вопросы

Урок «Модель компонентов Blazor» бесплатный?

Да — полный текст урока «Модель компонентов Blazor» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C# Academy, подпишись на CoddyKit PRO. Курс C# Academy содержит 4 уроков всего.

Чему я научусь в уроке «Модель компонентов Blazor»?

Создавайте компоненты Razor, разбирайтесь в жизненном цикле компонентов и используйте параметры и каскадные значения. Ты практикуешь C# Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать C# Academy?

Предыдущий опыт не требуется. C# Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.

Сколько времени занимает урок «Модель компонентов Blazor»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке C# Academy?

Да. Каждый урок C# Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Модель компонентов Blazor
  2. Привязка данных и обработка событий
  3. Взаимодействие компонентов и DI
  4. Управление состоянием в Blazor
← Назад к C# Academy