0Pricing
C# Academy · Lekcja

Model komponentów Blazor

Twórz komponenty Razor, poznaj cykl życia komponentu oraz używaj parametrów i wartości kaskadowych.

Model komponentów Blazor to bezpłatna lekcja C# Academy na CoddyKit. To lekcja 1 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej C# Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs C# Academy zawiera 4 lekcji w sumie.

Czym jest Blazor?

Blazor umożliwia tworzenie interaktywnych interfejsów internetowych przy użyciu C# zamiast JavaScript. Komponenty definiuje się w plikach .razor, które łączą znaczniki HTML z logiką C#. Blazor działa na serwerze (Blazor Server) lub w przeglądarce za pośrednictwem WebAssembly (Blazor WASM).

Pierwszy komponent

Komponent Razor to plik .razor zawierający znaczniki HTML oraz blok @code z kodem C#. Nazwa komponentu staje się nazwą znacznika 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;
}

Cykl życia komponentu

Komponenty Blazor mają cykl życia z punktami zaczepienia, które można przesłaniać. Najczęściej używane są OnInitializedAsync (ładowanie danych) oraz OnParametersSetAsync (reagowanie na zmiany parametrów).

@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();
    }
}

Parametry: przekazywanie danych do komponentów

Należy oznaczyć właściwości atrybutem [Parameter], aby przyjmowały dane z komponentów nadrzędnych. Parametry są ustawiane przed renderowaniem, a ich zmiana może wywołać ponowne renderowanie.

@* 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);
}

Parametry kaskadowe

Parametry kaskadowe przepływają w dół drzewa komponentów bez konieczności jawnego przekazywania ich przez każdy poziom pośredni — idealnie nadają się do motywów, informacji o użytkowniku lub współdzielonego stanu.

@* 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!;
}

Renderowanie list i warunków

Do renderowania dynamicznej zawartości należy używać dyrektyw Razor @if, @foreach i @for. Elementom listy należy zawsze nadawać @key, aby wydajnie wykrywać różnice.

@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 i ChildContent

Należy używać RenderFragment do przekazywania znaczników jako parametru — podobnie jak slotów w Vue lub children w React. Konwencjonalna nazwa parametru to 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>

Referencje do komponentów za pomocą @ref

Za pomocą @ref można przechwycić referencję do komponentu podrzędnego, aby wywoływać jego publiczne metody lub odczytywać jego właściwości z komponentu nadrzędnego.

@* 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 i ręczne ponowne renderowanie

Blazor automatycznie renderuje komponent ponownie po wykonaniu procedur obsługi zdarzeń. W przypadku asynchronicznych zmian stanu poza procedurami obsługi zdarzeń (np. wywołanych przez czasomierz działający w tle) należy ręcznie wywołać 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 na potrzeby wydajności

Należy przesłonić ShouldRender(), aby pomijać niepotrzebne ponowne renderowanie. Gdy dane wyjściowe komponentu się nie zmienią, należy zwrócić false, ograniczając koszt wykrywania różnic.

@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;
    }
}

Praktyczny przykład: komponent listy produktów

Kompletny komponent listy produktów, który ładuje dane podczas inicjalizacji, obsługuje stan ładowania i przekazuje zdarzenia do komponentu nadrzędnego.

@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);
}

Szybkie sprawdzenie

W której metodzie cyklu życia najlepiej ładować dane z API podczas inicjalizacji komponentu Blazor?

Podsumowanie: model komponentów Blazor

Najważniejsze informacje:

  • Pliki .razor łączą znaczniki HTML z kodem C# w bloku @code
  • [Parameter] przyjmuje dane od komponentu nadrzędnego, a EventCallback przekazuje zdarzenia w górę
  • CascadingParameter przekazuje dane w dół bez prop-drillingu
  • RenderFragment/ChildContent umożliwia tworzenie komponowalnych komponentów opartych na slotach
  • OnInitializedAsync służy do początkowego ładowania danych, a StateHasChanged do ręcznego ponownego renderowania
  • ShouldRender() pomija niepotrzebne wykrywanie różnic, zwiększając wydajność

Często zadawane pytania

Czy lekcja „Model komponentów Blazor” jest bezpłatna?

Tak — pełny tekst „Model komponentów Blazor” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu C# Academy, przejdź na CoddyKit PRO. Kurs C# Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Model komponentów Blazor”?

Twórz komponenty Razor, poznaj cykl życia komponentu oraz używaj parametrów i wartości kaskadowych. Ćwiczysz C# Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć C# Academy?

Nie wymagamy żadnego doświadczenia. C# Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 1 z 4.

Ile czasu zajmuje lekcja „Model komponentów Blazor”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji C# Academy?

Tak. Każda lekcja C# Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Model komponentów Blazor
  2. Wiązanie danych i obsługa zdarzeń
  3. Komunikacja komponentów i DI
  4. Zarządzanie stanem w Blazor
← Powrót do C# Academy