ASP.NET Core Razor コンポーネントの作成と使用Create and use ASP.NET Core Razor components

作成者: Luke LathamDaniel RothTobias BartschBy Luke Latham, Daniel Roth, and Tobias Bartsch

サンプル コードを表示またはダウンロードします (ダウンロード方法)。View or download sample code (how to download)

Blazor アプリは コンポーネントを使用してビルドします。Blazor apps are built using components. コンポーネントは、ページ、ダイアログ、フォームなどのユーザー インターフェイス (UI) の自己完結型のチャンクです。A component is a self-contained chunk of user interface (UI), such as a page, dialog, or form. コンポーネントには、データの挿入や UI イベントへの応答に必要な HTML マークアップと、処理ロジックが含まれます。A component includes HTML markup and the processing logic required to inject data or respond to UI events. コンポーネントは、柔軟性があり、軽量です。Components are flexible and lightweight. それらを入れ子にしたり、再利用したり、プロジェクト間で共有したりできます。They can be nested, reused, and shared among projects.

コンポーネント クラスComponent classes

コンポーネントは、C# と HTML マークアップの組み合わせを使用して、Razor コンポーネント ファイル (.razor) で実装します。Components are implemented in Razor component files (.razor) using a combination of C# and HTML markup. Blazor のコンポーネントは、正式には Razor コンポーネント と呼ばれます。A component in Blazor is formally referred to as a Razor component.

Razor の構文Razor syntax

Blazor アプリの Razor コンポーネントでは、Razor 構文が多用されます。Razor components in Blazor apps extensively use Razor syntax. Razor マークアップ言語に慣れていない場合は、先に進む前に「ASP.NET Core の razor 構文リファレンス」を読むことをお勧めします。If you aren't familiar with the Razor markup language, we recommend reading ASP.NET Core の razor 構文リファレンス before proceeding.

Razor 構文でコンテンツにアクセスする場合は、次のセクションに特にご注意ください。When accessing the content on Razor syntax, pay special attention to the following sections:

  • ディレクティブ: 通常はコンポーネント マークアップの解析方法や機能を変更する、@ プレフィックス付きの予約キーワード。Directives: @-prefixed reserved keywords that typically change the way component markup is parsed or function.
  • ディレクティブ属性: 通常はコンポーネント要素の解析方法や機能を変更する、@ プレフィックス付きの予約キーワード。Directive attributes: @-prefixed reserved keywords that typically change the way component elements are parsed or function.

名前Names

コンポーネントの名前は、大文字で始める必要があります。A component's name must start with an uppercase character. たとえば、MyCoolComponent.razor は有効で、myCoolComponent.razor は無効です。For example, MyCoolComponent.razor is valid, and myCoolComponent.razor is invalid.

ルーティングRouting

Blazor でのルーティングは、アプリ内のアクセス可能な各コンポーネントへのルート テンプレートを提供することで実現します。Routing in Blazor is achieved by providing a route template to each accessible component in the app. @page ディレクティブを含む Razor ファイルがコンパイルされると、生成されたクラスに、ルート テンプレートを指定する RouteAttribute が指定されます。When a Razor file with an @page directive is compiled, the generated class is given a RouteAttribute specifying the route template. 実行時に、ルーターによって RouteAttribute を持つコンポーネント クラスが検索され、要求された URL に一致するルート テンプレートを使用するコンポーネントがレンダリングされます。At runtime, the router looks for component classes with a RouteAttribute and renders whichever component has a route template that matches the requested URL. 詳細については、「ASP.NET Core Blazor のルーティング」を参照してください。For more information, see ASP.NET Core Blazor のルーティング.

@page "/ParentComponent"

...

マークアップMarkup

コンポーネントの UI は、HTML を使用して定義します。The UI for a component is defined using HTML. 動的なレンダリング ロジック (たとえばループ、条件、式) が、 Razor と呼ばれる埋め込みの C# 構文を使って追加されています。Dynamic rendering logic (for example, loops, conditionals, expressions) is added using an embedded C# syntax called Razor. アプリがコンパイルされると、HTML マークアップと C# のレンダリング ロジックはコンポーネント クラスに変換されます。When an app is compiled, the HTML markup and C# rendering logic are converted into a component class. 生成されたクラスの名前は、ファイルの名前と一致します。The name of the generated class matches the name of the file.

コンポーネント クラスのメンバーは、@code ブロック内で定義されています。Members of the component class are defined in an @code block. @code ブロックには、イベント処理のメソッド、またはその他のコンポーネント ロジックを定義するためのメソッドによって、コンポーネントの状態 (プロパティ、フィールド) を指定します。In the @code block, component state (properties, fields) is specified with methods for event handling or for defining other component logic. 複数の @code ブロックが許容されます。More than one @code block is permissible.

コンポーネント メンバーは、@ で始まる C# 式を使用して、コンポーネントのレンダリング ロジックの一部として使用できます。Component members can be used as part of the component's rendering logic using C# expressions that start with @. たとえば、フィールド名の前に @ を付けることによって、C# フィールドがレンダリングされます。For example, a C# field is rendered by prefixing @ to the field name. 次の例では、以下のように評価され、レンダリングされます。The following example evaluates and renders:

  • headingFontStylefont-style の CSS プロパティ値に。headingFontStyle to the CSS property value for font-style.
  • headingText<h1> 要素のコンテンツに。headingText to the content of the <h1> element.
<h1 style="font-style:@headingFontStyle">@headingText</h1>

@code {
    private string headingFontStyle = "italic";
    private string headingText = "Put on your new Blazor!";
}

コンポーネントが最初にレンダリングされた後に、コンポーネントがイベントに応答して、レンダリング ツリーを再生成します。After the component is initially rendered, the component regenerates its render tree in response to events. Blazor によって新旧のレンダリング ツリーが比較され、ブラウザーのドキュメント オブジェクト モデル (DOM) に変更が適用されます。Blazor then compares the new render tree against the previous one and applies any modifications to the browser's Document Object Model (DOM).

コンポーネントは通常の C# クラスであり、プロジェクト内の任意の場所に配置できます。Components are ordinary C# classes and can be placed anywhere within a project. Web ページを生成するコンポーネントは、通常、Pages フォルダーに存在します。Components that produce webpages usually reside in the Pages folder. ページ以外のコンポーネントは、多くの場合、Shared フォルダー、またはプロジェクトに追加されたカスタム フォルダーに配置されます。Non-page components are frequently placed in the Shared folder or a custom folder added to the project.

名前空間Namespaces

一般に、コンポーネントの名前空間は、アプリのルート名前空間と、アプリ内のコンポーネントの場所 (フォルダー) から派生します。Typically, a component's namespace is derived from the app's root namespace and the component's location (folder) within the app. アプリのルート名前空間が BlazorSample で、Counter コンポーネントが Pages フォルダーに存在する場合:If the app's root namespace is BlazorSample and the Counter component resides in the Pages folder:

  • Counter コンポーネントの名前空間は BlazorSample.Pages になります。The Counter component's namespace is BlazorSample.Pages.
  • コンポーネントの完全修飾型名は BlazorSample.Pages.Counter になります。The fully qualified type name of the component is BlazorSample.Pages.Counter.

コンポーネントを保持するカスタム フォルダーの場合は、@using ディレクティブを親コンポーネントまたはアプリの _Imports.razor ファイルに追加します。For custom folders that hold components, add a @using directive to the parent component or to the app's _Imports.razor file. 次の例では、Components フォルダー内のコンポーネントを使用できるようにします。The following example makes components in the Components folder available:

@using BlazorSample.Components

コンポーネントは、完全修飾名を使用して参照することもできます。この場合、@using ディレクティブは必要ありません。Components can also be referenced using their fully qualified names, which doesn't require the @using directive:

<BlazorSample.Components.MyComponent />

Razor で作成されるコンポーネントの名前空間は、次に基づきます (優先順)。The namespace of a component authored with Razor is based on (in priority order):

  • Razor ファイル (.razor) マークアップ内の @namespace の指定 (@namespace BlazorSample.MyNamespace)。@namespace designation in Razor file (.razor) markup (@namespace BlazorSample.MyNamespace).
  • プロジェクト ファイル内のプロジェクトの RootNamespace (<RootNamespace>BlazorSample</RootNamespace>)。The project's RootNamespace in the project file (<RootNamespace>BlazorSample</RootNamespace>).
  • プロジェクト ファイルのファイル名 (.csproj) から取得されたプロジェクト名、およびプロジェクト ルートからコンポーネントへのパス。The project name, taken from the project file's file name (.csproj), and the path from the project root to the component. たとえば、フレームワークでは {PROJECT ROOT}/Pages/Index.razor (BlazorSample.csproj) が名前空間 BlazorSample.Pages に解決されます。For example, the framework resolves {PROJECT ROOT}/Pages/Index.razor (BlazorSample.csproj) to the namespace BlazorSample.Pages. コンポーネントは C# の名前のバインド規則に従います。Components follow C# name binding rules. この例の Index コンポーネントの場合、スコープ内のコンポーネントは、次のすべてのコンポーネントです。For the Index component in this example, the components in scope are all of the components:
    • 同じフォルダー (Pages) に含まれるもの。In the same folder, Pages.
    • 別の名前空間を明示的に指定しない、プロジェクトのルート内のコンポーネント。The components in the project's root that don't explicitly specify a different namespace.

注意

global:: 修飾はサポートされていません。The global:: qualification isn't supported.

別名が付けられた using ステートメント (@using Foo = Bar など) によるコンポーネントのインポートはサポートされていません。Importing components with aliased using statements (for example, @using Foo = Bar) isn't supported.

部分修飾名はサポートされていません。Partially qualified names aren't supported. たとえば、<Shared.NavMenu></Shared.NavMenu> による @using BlazorSample の追加と NavMenu コンポーネント (NavMenu.razor) の参照はサポートされていません。For example, adding @using BlazorSample and referencing the NavMenu component (NavMenu.razor) with <Shared.NavMenu></Shared.NavMenu> isn't supported.

部分クラスのサポートPartial class support

Razor コンポーネントは、部分クラスとして生成されます。Razor components are generated as partial classes. Razor コンポーネントは、次のいずれかの方法を使用して作成します。Razor components are authored using either of the following approaches:

  • C# コードは、1 つのファイルに HTML マークアップと Razor コードを含む @code ブロックで定義します。C# code is defined in an @code block with HTML markup and Razor code in a single file. Blazor テンプレートでは、この方法を使用して Razor コンポーネントを定義します。Blazor templates define their Razor components using this approach.
  • C# コードは、部分クラスとして定義されている分離コード ファイルに配置されます。C# code is placed in a code-behind file defined as a partial class.

次の例は、Blazor テンプレートから生成されたアプリ内の @code ブロックを含む既定の Counter コンポーネントを示しています。The following example shows the default Counter component with an @code block in an app generated from a Blazor template. HTML マークアップ、Razor コード、C# コードは、同じファイル内にあります。HTML markup, Razor code, and C# code are in the same file:

Pages/Counter.razor:Pages/Counter.razor:

@page "/counter"

<h1>Counter</h1>

<p>Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
    private int currentCount = 0;

    void IncrementCount()
    {
        currentCount++;
    }
}

Counter コンポーネントは、部分クラスを含む分離コード ファイルを使用して作成することもできます。The Counter component can also be created using a code-behind file with a partial class:

Pages/Counter.razor:Pages/Counter.razor:

@page "/counter"

<h1>Counter</h1>

<p>Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

Counter.razor.cs:Counter.razor.cs:

namespace BlazorSample.Pages
{
    public partial class Counter
    {
        private int currentCount = 0;

        void IncrementCount()
        {
            currentCount++;
        }
    }
}

必要に応じて、部分クラスファイルに必要な名前空間を追加します。Add any required namespaces to the partial class file as needed. Razor コンポーネントで使用される一般的な名前空間には次のものが含まれます。Typical namespaces used by Razor components include:

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.AspNetCore.Components.Routing;
using Microsoft.AspNetCore.Components.Web;

重要

_Imports.razor ファイルの @using ディレクティブは、C# ファイル (.cs) ではなく Razor ファイル (.razor) にのみ適用されます。@using directives in the _Imports.razor file are only applied to Razor files (.razor), not C# files (.cs).

基本クラスの指定Specify a base class

@inherits ディレクティブを使用して、コンポーネントの基本クラスを指定できます。The @inherits directive can be used to specify a base class for a component. 次の例は、コンポーネントが基本クラス BlazorRocksBase を継承して、コンポーネントのプロパティとメソッドを提供する方法を示しています。The following example shows how a component can inherit a base class, BlazorRocksBase, to provide the component's properties and methods. 基本クラスは ComponentBase から派生する必要があります。The base class should derive from ComponentBase.

Pages/BlazorRocks.razor:Pages/BlazorRocks.razor:

@page "/BlazorRocks"
@inherits BlazorRocksBase

<h1>@BlazorRocksText</h1>

BlazorRocksBase.cs:BlazorRocksBase.cs:

using Microsoft.AspNetCore.Components;

namespace BlazorSample
{
    public class BlazorRocksBase : ComponentBase
    {
        public string BlazorRocksText { get; set; } = 
            "Blazor rocks the browser!";
    }
}

コンポーネントを使うUse components

コンポーネントには、HTML 要素構文を使用して宣言することで、他のコンポーネントを含めることができます。Components can include other components by declaring them using HTML element syntax. コンポーネントを使うためのマークアップは、そのコンポーネントの種類をタグ名とする HTML タグのようになります。The markup for using a component looks like an HTML tag where the name of the tag is the component type.

Pages/Index.razor の次のマークアップでは、HeadingComponent インスタンスがレンダリングされます。The following markup in Pages/Index.razor renders a HeadingComponent instance:

<HeadingComponent />

Components/HeadingComponent.razor:Components/HeadingComponent.razor:

@using System.Globalization

<h1 style="font-style:@headingFontStyle">@headingText</h1>

<form>
    <div>
        <label class="form-check-label">
            <input type="checkbox" id="italicsCheck" 
               @bind="italicsCheck" />
            Use italics
        </label>
    </div>

    <button type="button" class="btn btn-primary" @onclick="UpdateHeading">
        Update heading
    </button>
</form>

@code {
    private static TextInfo tinfo = CultureInfo.CurrentCulture.TextInfo;
    private string headingText = 
        tinfo.ToTitleCase("welcome to blazor!");
    private string headingFontStyle = "normal";
    private bool italicsCheck = false;

    public void UpdateHeading()
    {
        headingFontStyle = italicsCheck ? "italic" : "normal";
    }
}

コンポーネント名と一致しない最初の文字が大文字の HTML 要素がコンポーネントに含まれている場合、要素に予期しない名前が付いていることを示す警告が出力されます。If a component contains an HTML element with an uppercase first letter that doesn't match a component name, a warning is emitted indicating that the element has an unexpected name. コンポーネントの名前空間に @using ディレクティブを追加すると、コンポーネントを使用できるようになり、警告が解決されます。Adding an @using directive for the component's namespace makes the component available, which resolves the warning.

パラメーターParameters

ルート パラメーターRoute parameters

コンポーネントでは、@page ディレクティブに指定されたルート テンプレートからルート パラメーターを受け取ることができます。Components can receive route parameters from the route template provided in the @page directive. ルーターでは、ルート パラメーターを使用して、対応するコンポーネント パラメーターが設定されます。The router uses route parameters to populate the corresponding component parameters.

Pages/RouteParameter.razor:Pages/RouteParameter.razor:

@page "/RouteParameter"
@page "/RouteParameter/{text}"

<h1>Blazor is @Text!</h1>

@code {
    [Parameter]
    public string Text { get; set; }

    protected override void OnInitialized()
    {
        Text = Text ?? "fantastic";
    }
}

オプションのパラメーターはサポートされていないため、前の例では 2 つの @page ディレクティブが適用されます。Optional parameters aren't supported, so two @page directives are applied in the preceding example. 1 つ目は、パラメーターを指定せずにコンポーネントへの移動を許可します。The first permits navigation to the component without a parameter. 2 番目の @page ディレクティブでは、{text} ルート パラメーターを受け取り、その値を Text プロパティに割り当てます。The second @page directive receives the {text} route parameter and assigns the value to the Text property.

複数のフォルダーにわたりパスをキャプチャするキャッチオール ルート パラメーター ({*pageRoute}) の詳細については、「ASP.NET Core Blazor のルーティング」を参照してください。For information on catch-all route parameters ({*pageRoute}), which capture paths across multiple folder boundaries, see ASP.NET Core Blazor のルーティング.

コンポーネントのパラメーターComponent parameters

コンポーネントには、コンポーネント パラメーターを指定できます。このパラメーターは、[Parameter] 属性を指定したコンポーネント クラス上で、パブリック プロパティを使用して定義します。Components can have component parameters, which are defined using public properties on the component class with the [Parameter] attribute. マークアップ内でコンポーネントの引数を指定するには、属性を使います。Use attributes to specify arguments for a component in markup.

Components/ChildComponent.razor:Components/ChildComponent.razor:

<div class="panel panel-default">
    <div class="panel-heading">@Title</div>
    <div class="panel-body">@ChildContent</div>

    <button class="btn btn-primary" @onclick="OnClickCallback">
        Trigger a Parent component method
    </button>
</div>

@code {
    [Parameter]
    public string Title { get; set; }

    [Parameter]
    public RenderFragment ChildContent { get; set; }

    [Parameter]
    public EventCallback<MouseEventArgs> OnClickCallback { get; set; }
}

サンプル アプリの次の例では、ParentComponent によって ChildComponentTitle プロパティの値を設定しています。In the following example from the sample app, the ParentComponent sets the value of the Title property of the ChildComponent.

Pages/ParentComponent.razor:Pages/ParentComponent.razor:

@page "/ParentComponent"

<h1>Parent-child example</h1>

<ChildComponent Title="Panel Title from Parent"
                OnClickCallback="@ShowMessage">
    Content of the child component is supplied
    by the parent component.
</ChildComponent>

警告

独自の "コンポーネント パラメーター" を書き込み先とするコンポーネントを作成する代わりに、プライベート フィールドを使用してください。Don't create components that write to their own component parameters, use a private field instead. 詳細については、「上書きされたパラメーター」セクションをご覧ください。For more information, see the Overwritten parameters section.

子コンテンツChild content

コンポーネントでは、別のコンポーネントのコンテンツを設定できます。Components can set the content of another component. 割り当てコンポーネントでは、受信コンポーネントを指定するタグ間にコンテンツを指定します。The assigning component provides the content between the tags that specify the receiving component.

次の例では、ChildComponent に、レンダリングする UI のセグメントを表す RenderFragment を表す ChildContent プロパティがあります。In the following example, the ChildComponent has a ChildContent property that represents a RenderFragment, which represents a segment of UI to render. コンテンツをレンダリングする必要があるコンポーネントのマークアップに、ChildContent の値を配置します。The value of ChildContent is positioned in the component's markup where the content should be rendered. ChildContent の値は、親コンポーネントから受け取られ、ブートストラップ パネルの panel-body 内にレンダリングされます。The value of ChildContent is received from the parent component and rendered inside the Bootstrap panel's panel-body.

Components/ChildComponent.razor:Components/ChildComponent.razor:

<div class="panel panel-default">
    <div class="panel-heading">@Title</div>
    <div class="panel-body">@ChildContent</div>

    <button class="btn btn-primary" @onclick="OnClickCallback">
        Trigger a Parent component method
    </button>
</div>

@code {
    [Parameter]
    public string Title { get; set; }

    [Parameter]
    public RenderFragment ChildContent { get; set; }

    [Parameter]
    public EventCallback<MouseEventArgs> OnClickCallback { get; set; }
}

注意

RenderFragment コンテンツを受け取るプロパティは、規則によって ChildContent という名前にする必要があります。The property receiving the RenderFragment content must be named ChildContent by convention.

サンプル アプリの ParentComponent では、コンテンツを <ChildComponent> タグ内に配置することによって、ChildComponent をレンダリングするためのコンテンツを提供できます。The ParentComponent in the sample app can provide content for rendering the ChildComponent by placing the content inside the <ChildComponent> tags.

Pages/ParentComponent.razor:Pages/ParentComponent.razor:

@page "/ParentComponent"

<h1>Parent-child example</h1>

<ChildComponent Title="Panel Title from Parent"
                OnClickCallback="@ShowMessage">
    Content of the child component is supplied
    by the parent component.
</ChildComponent>

Blazor による子コンテンツのレンダリング方法により、for ループ内のコンポーネントのレンダリングでは、インクリメントするループ変数が子コンポーネントのコンテンツ内で使用されている場合、ローカル インデックス変数が必要になります。Due to the way that Blazor renders child content, rendering components inside a for loop requires a local index variable if the incrementing loop variable is used in the child component's content:

@for (int c = 0; c < 10; c++)
{
    var current = c;
    <ChildComponent Param1="@c">
        Child Content: Count: @current
    </ChildComponent>
}

または、Enumerable.Range と共に foreach ループを使用します。Alternatively, use a foreach loop with Enumerable.Range:

@foreach(var c in Enumerable.Range(0,10))
{
    <ChildComponent Param1="@c">
        Child Content: Count: @c
    </ChildComponent>
}

属性スプラッティングと任意のパラメーターAttribute splatting and arbitrary parameters

コンポーネントでは、コンポーネントの宣言されたパラメーターに加えて、追加の属性をキャプチャしてレンダリングできます。Components can capture and render additional attributes in addition to the component's declared parameters. 追加の属性は、ディクショナリにキャプチャし、@attributes Razor ディレクティブを使用して、コンポーネントがレンダリングされるときに、要素に "スプラッティング" できます。Additional attributes can be captured in a dictionary and then splatted onto an element when the component is rendered using the @attributes Razor directive. このシナリオは、さまざまなカスタマイズをサポートするマークアップ要素を生成するコンポーネントを定義する場合に便利です。This scenario is useful when defining a component that produces a markup element that supports a variety of customizations. たとえば、多くのパラメーターをサポートする <input> に対して、属性を個別に定義するのは面倒な場合があります。For example, it can be tedious to define attributes separately for an <input> that supports many parameters.

次の例で、最初の <input> 要素 (id="useIndividualParams") では、個々のコンポーネント パラメーターを使用していますが、2 番目の <input> 要素 (id="useAttributesDict") では、属性スプラッティングを使用しています。In the following example, the first <input> element (id="useIndividualParams") uses individual component parameters, while the second <input> element (id="useAttributesDict") uses attribute splatting:

<input id="useIndividualParams"
       maxlength="@maxlength"
       placeholder="@placeholder"
       required="@required"
       size="@size" />

<input id="useAttributesDict"
       @attributes="InputAttributes" />

@code {
    public string maxlength = "10";
    public string placeholder = "Input placeholder text";
    public string required = "required";
    public string size = "50";

    public Dictionary<string, object> InputAttributes { get; set; } =
        new Dictionary<string, object>()
        {
            { "maxlength", "10" },
            { "placeholder", "Input placeholder text" },
            { "required", "required" },
            { "size", "50" }
        };
}

パラメーターの型は、文字列キーで IEnumerable<KeyValuePair<string, object>> または IReadOnlyDictionary<string, object> を実装する必要があります。The type of the parameter must implement IEnumerable<KeyValuePair<string, object>> or IReadOnlyDictionary<string, object> with string keys.

両方の方法を使用してレンダリングされる <input> 要素は同じです。The rendered <input> elements using both approaches is identical:

<input id="useIndividualParams"
       maxlength="10"
       placeholder="Input placeholder text"
       required="required"
       size="50">

<input id="useAttributesDict"
       maxlength="10"
       placeholder="Input placeholder text"
       required="required"
       size="50">

任意の属性を受け入れるには、CaptureUnmatchedValues プロパティを true に設定した [Parameter] 属性を使用して、コンポーネント パラメーターを定義します。To accept arbitrary attributes, define a component parameter using the [Parameter] attribute with the CaptureUnmatchedValues property set to true:

@code {
    [Parameter(CaptureUnmatchedValues = true)]
    public Dictionary<string, object> InputAttributes { get; set; }
}

[Parameter]CaptureUnmatchedValues プロパティにより、パラメーターを他のパラメーターと一致しないすべての属性と一致させることができます。The CaptureUnmatchedValues property on [Parameter] allows the parameter to match all attributes that don't match any other parameter. 1 つのコンポーネントで、CaptureUnmatchedValues を持つパラメーターは 1 つだけ定義できます。A component can only define a single parameter with CaptureUnmatchedValues. CaptureUnmatchedValues で使用されるプロパティの型は、文字列キーを使用して Dictionary<string, object> から割り当て可能である必要があります。The property type used with CaptureUnmatchedValues must be assignable from Dictionary<string, object> with string keys. このシナリオでは、IEnumerable<KeyValuePair<string, object>> または IReadOnlyDictionary<string, object> も使用できます。IEnumerable<KeyValuePair<string, object>> or IReadOnlyDictionary<string, object> are also options in this scenario.

要素属性の位置を基準とした @attributes の位置は重要です。The position of @attributes relative to the position of element attributes is important. @attributes が要素にスプラッティングされると、属性は右から左 (最後から最初) に処理されます。When @attributes are splatted on the element, the attributes are processed from right to left (last to first). Child コンポーネントを使用する次のコンポーネントの例を考えます。Consider the following example of a component that consumes a Child component:

ParentComponent.razor:ParentComponent.razor:

<ChildComponent extra="10" />

ChildComponent.razor:ChildComponent.razor:

<div @attributes="AdditionalAttributes" extra="5" />

[Parameter(CaptureUnmatchedValues = true)]
public IDictionary<string, object> AdditionalAttributes { get; set; }

Child コンポーネントの extra 属性が @attributes の右側に設定されています。The Child component's extra attribute is set to the right of @attributes. 属性は右から左 (最後から最初) に処理されるため、追加の属性によって渡された場合に、Parent コンポーネントのレンダリングされる <div> に、extra="5" が含まれます。The Parent component's rendered <div> contains extra="5" when passed through the additional attribute because the attributes are processed right to left (last to first):

<div extra="5" />

次の例では、Child コンポーネントの <div> で、extra@attributes の順序が逆になります。In the following example, the order of extra and @attributes is reversed in the Child component's <div>:

ParentComponent.razor:ParentComponent.razor:

<ChildComponent extra="10" />

ChildComponent.razor:ChildComponent.razor:

<div extra="5" @attributes="AdditionalAttributes" />

[Parameter(CaptureUnmatchedValues = true)]
public IDictionary<string, object> AdditionalAttributes { get; set; }

追加の属性によって渡された場合に、Parent コンポーネント内のレンダリングされる <div> には、extra="10" が含まれます。The rendered <div> in the Parent component contains extra="10" when passed through the additional attribute:

<div extra="10" />

コンポーネントへの参照をキャプチャするCapture references to components

コンポーネント参照によって、コンポーネント インスタンスを参照する方法が得られるため、そのインスタンスに ShowReset などのコマンドを発行できます。Component references provide a way to reference a component instance so that you can issue commands to that instance, such as Show or Reset. コンポーネント参照をキャプチャするには:To capture a component reference:

  • 子コンポーネントに @ref 属性を追加します。Add an @ref attribute to the child component.
  • 子コンポーネントと同じ型のフィールドを定義します。Define a field with the same type as the child component.
<CustomLoginDialog @ref="loginDialog" ... />

@code {
    private CustomLoginDialog loginDialog;

    private void OnSomething()
    {
        loginDialog.Show();
    }
}

コンポーネントがレンダリングされると、loginDialog フィールドに MyLoginDialog 子コンポーネント インスタンスが設定されます。When the component is rendered, the loginDialog field is populated with the MyLoginDialog child component instance. これにより、コンポーネント インスタンスに対し、.NET メソッドを呼び出すことができます。You can then invoke .NET methods on the component instance.

重要

loginDialog 変数は、コンポーネントがレンダリングされた後にのみ設定され、その出力には MyLoginDialog 要素が含まれます。The loginDialog variable is only populated after the component is rendered and its output includes the MyLoginDialog element. コンポーネントがレンダリングされるまで、参照するものはありません。Until the component is rendered, there's nothing to reference.

コンポーネントのレンダリングが完了した後にコンポーネント参照を操作するには、OnAfterRenderAsyncメソッドまたは OnAfterRender メソッドを使用します。To manipulate components references after the component has finished rendering, use the OnAfterRenderAsync or OnAfterRender methods.

イベント ハンドラーで参照変数を使用するには、ラムダ式を使用するか、OnAfterRenderAsync または OnAfterRender メソッドでイベント ハンドラー デリゲートを割り当てます。To use a reference variable with an event handler, use a lambda expression or assign the event handler delegate in the OnAfterRenderAsync or OnAfterRender methods. これにより、イベント ハンドラーが割り当てられる前に参照変数が確実に割り当てられます。This ensures that the reference variable is assigned before the event handler is assigned.

<button type="button" 
    @onclick="@(() => loginDialog.DoSomething())">Do Something</button>

<MyLoginDialog @ref="loginDialog" ... />

@code {
    private MyLoginDialog loginDialog;
}

ループ内のコンポーネントを参照するには、「Capture references to multiple similar child-components」(複数の類似した子コンポーネントへの参照をキャプチャする) (dotnet/aspnetcore #13358) を参照してください。To reference components in a loop, see Capture references to multiple similar child-components (dotnet/aspnetcore #13358).

コンポーネント参照のキャプチャでは、要素参照のキャプチャと類似の構文を使用しますが、それは JavaScript 相互運用機能ではありません。While capturing component references use a similar syntax to capturing element references, it isn't a JavaScript interop feature. コンポーネント参照は、JavaScript コードに渡されません。Component references aren't passed to JavaScript code. コンポーネント参照は、.NET コードでのみ使用されます。Component references are only used in .NET code.

注意

子コンポーネントの状態を変えるためにコンポーネント参照を使用しないでください。Do not use component references to mutate the state of child components. 代わりに、通常の宣言型パラメーターを使用して、子コンポーネントにデータを渡します。Instead, use normal declarative parameters to pass data to child components. 通常の宣言型パラメーターを使用すると、子コンポーネントが正しいタイミングで自動的にレンダリングされます。Use of normal declarative parameters result in child components that rerender at the correct times automatically.

同期コンテキストSynchronization context

Blazor では、同期コンテキスト (SynchronizationContext) を使用して、1 つの実行の論理スレッドを強制します。Blazor uses a synchronization context (SynchronizationContext) to enforce a single logical thread of execution. コンポーネントのライフサイクル メソッドと、Blazor によって発生するすべてのイベント コールバックは、同期コンテキストで実行されます。A component's lifecycle methods and any event callbacks that are raised by Blazor are executed on the synchronization context.

Blazor Server の同期コンテキストでは、ブラウザーの WebAssembly モデル (シングル スレッド) と厳密に一致するように、シングルスレッド環境のエミュレートが試行されます。Blazor Server's synchronization context attempts to emulate a single-threaded environment so that it closely matches the WebAssembly model in the browser, which is single threaded. どの時点でも、作業は 1 つのスレッドでのみ実行され、1 つの論理スレッドであるという印象になります。At any given point in time, work is performed on exactly one thread, giving the impression of a single logical thread. 2 つの操作が同時に実行されることはありません。No two operations execute concurrently.

スレッドをブロックする呼び出しを避けるAvoid thread-blocking calls

一般に、次のメソッドは呼び出さないでください。Generally, don't call the following methods. 次のメソッドでは、スレッドがブロックされます。そのため、基になる Task が完了するまで、アプリの動作が再開されなくなります。The following methods block the thread and thus block the app from resuming work until the underlying Task is complete:

状態を更新するために外部でコンポーネント メソッドを呼び出すInvoke component methods externally to update state

タイマーやその他の通知などの外部のイベントに基づいてコンポーネントを更新する必要がある場合は、InvokeAsync メソッドを使用します。これにより、Blazor の同期コンテキストにディスパッチされます。In the event a component must be updated based on an external event, such as a timer or other notifications, use the InvokeAsync method, which dispatches to Blazor's synchronization context. たとえば、リッスンしているコンポーネントに、更新状態を通知できる通知サービス を考えてみます。For example, consider a notifier service that can notify any listening component of the updated state:

public class NotifierService
{
    // Can be called from anywhere
    public async Task Update(string key, int value)
    {
        if (Notify != null)
        {
            await Notify.Invoke(key, value);
        }
    }

    public event Func<string, int, Task> Notify;
}

NotifierService を登録します。Register the NotifierService:

  • Blazor WebAssembly で、Program.Main のシングルトンとしてサービスを登録します。In Blazor WebAssembly, register the service as singleton in Program.Main:

    builder.Services.AddSingleton<NotifierService>();
    
  • Blazor Server で、Startup.ConfigureServices のスコープとしてサービスを登録します。In Blazor Server, register the service as scoped in Startup.ConfigureServices:

    services.AddScoped<NotifierService>();
    

NotifierService を使用して、コンポーネントを更新します。Use the NotifierService to update a component:

@page "/"
@inject NotifierService Notifier
@implements IDisposable

<p>Last update: @lastNotification.key = @lastNotification.value</p>

@code {
    private (string key, int value) lastNotification;

    protected override void OnInitialized()
    {
        Notifier.Notify += OnNotify;
    }

    public async Task OnNotify(string key, int value)
    {
        await InvokeAsync(() =>
        {
            lastNotification = (key, value);
            StateHasChanged();
        });
    }

    public void Dispose()
    {
        Notifier.Notify -= OnNotify;
    }
}

前の例では、Blazor の同期コンテキスト外で NotifierService からコンポーネントの OnNotify メソッドが呼び出されます。In the preceding example, NotifierService invokes the component's OnNotify method outside of Blazor's synchronization context. InvokeAsync を使用して、正しいコンテキストに切り替え、レンダリングをキューに登録します。InvokeAsync is used to switch to the correct context and queue a render.

@ キーを使用して要素とコンポーネントの保存を制御するUse @key to control the preservation of elements and components

要素またはコンポーネントのリストをレンダリングし、その後に要素またはコンポーネントが変更された場合、Blazor の比較アルゴリズムでは、前のどの要素やコンポーネントを保持できるか、およびモデル オブジェクトをそれらにどのようにマップするかを決定する必要があります。When rendering a list of elements or components and the elements or components subsequently change, Blazor's diffing algorithm must decide which of the previous elements or components can be retained and how model objects should map to them. 通常、このプロセスは自動で、無視できますが、プロセスの制御が必要になる場合があります。Normally, this process is automatic and can be ignored, but there are cases where you may want to control the process.

次に例を示します。Consider the following example:

@foreach (var person in People)
{
    <DetailsEditor Details="@person.Details" />
}

@code {
    [Parameter]
    public IEnumerable<Person> People { get; set; }
}

People コレクションのコンテンツは、挿入、削除、または順序変更されたエントリによって変更される可能性があります。The contents of the People collection may change with inserted, deleted, or re-ordered entries. コンポーネントのレンダリング時に、<DetailsEditor> コンポーネントが変更され、異なる Details パラメーター値を受け取ることがあります。When the component rerenders, the <DetailsEditor> component may change to receive different Details parameter values. これにより、予期したものよりも複雑な再レンダリングが発生する可能性があります。This may cause more complex rerendering than expected. 場合によっては、再レンダリングによって、要素のフォーカスの喪失などの表示動作の違いが発生する可能性があります。In some cases, rerendering can lead to visible behavior differences, such as lost element focus.

マッピング プロセスは、@key ディレクティブ属性を使用して制御できます。The mapping process can be controlled with the @key directive attribute. @key により、比較アルゴリズムで、キーの値に基づいて要素やコンポーネントが確実に保持されます。@key causes the diffing algorithm to guarantee preservation of elements or components based on the key's value:

@foreach (var person in People)
{
    <DetailsEditor @key="person" Details="@person.Details" />
}

@code {
    [Parameter]
    public IEnumerable<Person> People { get; set; }
}

People コレクションが変更されても、比較アルゴリズムによって、<DetailsEditor> インスタンスと person インスタンス間の関連付けが保持されます。When the People collection changes, the diffing algorithm retains the association between <DetailsEditor> instances and person instances:

  • PersonPeople リストから削除された場合、対応する <DetailsEditor> インスタンスだけが UI から削除されます。If a Person is deleted from the People list, only the corresponding <DetailsEditor> instance is removed from the UI. 他のインスタンスは変更されません。Other instances are left unchanged.
  • リスト内の特定の位置に Person が挿入されると、その対応する位置に、1 つの新しい <DetailsEditor> インスタンスが挿入されます。If a Person is inserted at some position in the list, one new <DetailsEditor> instance is inserted at that corresponding position. 他のインスタンスは変更されません。Other instances are left unchanged.
  • Person エントリの順序が変更された場合、対応する <DetailsEditor> インスタンスは UI で保持され、順序が変更されます。If Person entries are re-ordered, the corresponding <DetailsEditor> instances are preserved and re-ordered in the UI.

シナリオによっては、@key を使用すると、レンダリングの複雑さが最小限に抑えられ、フォーカス位置など、DOM 変更のステートフルな部分の潜在的な問題を回避できます。In some scenarios, use of @key minimizes the complexity of rerendering and avoids potential issues with stateful parts of the DOM changing, such as focus position.

重要

キーは、各コンテナー要素やコンポーネントに対してローカルです。Keys are local to each container element or component. キーはドキュメント全体でグローバルに比較されません。Keys aren't compared globally across the document.

@ キーを使用する場面When to use @key

一般に、リストがレンダリングされ (たとえば、foreach ブロックで)、@key を定義するための適切な値が存在する場合は常に、@key を使用することは意味があります。Typically, it makes sense to use @key whenever a list is rendered (for example, in a foreach block) and a suitable value exists to define the @key.

また、@key を使用して、オブジェクトが変更されたときに Blazor が要素やコンポーネントのサブツリーを保持しないようにすることもできます。You can also use @key to prevent Blazor from preserving an element or component subtree when an object changes:

<div @key="currentPerson">
    ... content that depends on currentPerson ...
</div>

@currentPerson が変更された場合、@key 属性ディレクティブによって、Blazor に、<div> とその子孫全体を破棄させ、新しい要素とコンポーネントで UI 内のサブツリーをリビルドさせます。If @currentPerson changes, the @key attribute directive forces Blazor to discard the entire <div> and its descendants and rebuild the subtree within the UI with new elements and components. これは、@currentPerson が変更されたときに、UI の状態が確実に保持されないようにする必要がある場合に役立つ可能性があります。This can be useful if you need to guarantee that no UI state is preserved when @currentPerson changes.

@ キーを使用しない場面When not to use @key

@key で比較すると、パフォーマンスが低下します。There's a performance cost when diffing with @key. パフォーマンスの低下は大きくありませんが、要素やコンポーネントの保存規則を制御することによって、アプリにメリットがある場合にのみ @key を指定してください。The performance cost isn't large, but only specify @key if controlling the element or component preservation rules benefit the app.

@key を使用しない場合でも、Blazor では可能な限り、子要素とコンポーネント インスタンスが保持されます。Even if @key isn't used, Blazor preserves child element and component instances as much as possible. @key を使用する唯一の利点は、マッピングを選択する比較アルゴリズムではなく、保持されているコンポーネント インスタンスにモデル インスタンスをマップする "方法" を制御することです。The only advantage to using @key is control over how model instances are mapped to the preserved component instances, instead of the diffing algorithm selecting the mapping.

@ キーに使用する値What values to use for @key

一般に、@key には、次のいずれかの種類の値を指定するのが適切です。Generally, it makes sense to supply one of the following kinds of value for @key:

  • モデル オブジェクトインスタンス (たとえば、前の例のように、Person インスタンス)。Model object instances (for example, a Person instance as in the earlier example). これにより、オブジェクト参照の等価性に基づいて保持されます。This ensures preservation based on object reference equality.
  • 一意の識別子 (たとえば、int 型、string 型、Guid 型の主キー値)。Unique identifiers (for example, primary key values of type int, string, or Guid).

@key に使用される値は確実に競合しないようにしてください。Ensure that values used for @key don't clash. 同じ親要素内で競合する値が検出された場合、Blazor では、古い要素やコンポーネントを新しい要素やコンポーネントに確定的にマップできないため、例外がスローされます。If clashing values are detected within the same parent element, Blazor throws an exception because it can't deterministically map old elements or components to new elements or components. 個別の値 (オブジェクト インスタンスや主キー値など) のみを使用してください。Only use distinct values, such as object instances or primary key values.

上書きされたパラメーターOverwritten parameters

親コンポーネントの再レンダリング時に、新しいパラメーター値が指定され、通常は既存のパラメーター値が上書きされます。New parameter values are supplied, typically overwriting existing ones, when the parent component rerenders.

次が実行される Expander コンポーネントについて考えてみましょう。Consider the following Expander component that:

  • 子コンテンツのレンダリング。Renders child content.
  • コンポーネント パラメーターを使用した、子コンテンツの表示の切り替え。Toggles showing child content with a component parameter.
<div @onclick="@Toggle" class="card bg-light mb-3" style="width:30rem">
    <div class="card-body">
        <h2 class="card-title">Toggle (<code>Expanded</code> = @Expanded)</h2>

        @if (Expanded)
        {
            <p class="card-text">@ChildContent</p>
        }
    </div>
</div>

@code {
    [Parameter]
    public bool Expanded { get; set; }

    [Parameter]
    public RenderFragment ChildContent { get; set; }

    private void Toggle()
    {
        Expanded = !Expanded;
    }
}

Expander コンポーネントは、StateHasChanged を呼び出す可能性のある親コンポーネントに追加されます。The Expander component is added to a parent component that may call StateHasChanged:

@page "/expander"

<Expander Expanded="true">
    Expander 1 content
</Expander>

<Expander Expanded="true" />

<button @onclick="StateHasChanged">
    Call StateHasChanged
</button>

初期状態では、Expanded プロパティが切り替えられると、Expander コンポーネントはそれぞれ独立して動作します。Initially, the Expander components behave independently when their Expanded properties are toggled. 子コンポーネントの状態は、想定どおりのままです。The child components maintain their states as expected. 親で StateHasChanged が呼び出されると、最初の子コンポーネントの Expanded パラメーターが初期値 (true) にリセットされます。When StateHasChanged is called in the parent, the Expanded parameter of the first child component is reset back to its initial value (true). 2 つめの Expander コンポーネントの Expanded 値はリセットされません。これは、2 つめのコンポーネントでは子コンテンツがレンダリングされないためです。The second Expander component's Expanded value isn't reset because no child content is rendered in the second component.

前のシナリオでの状態を維持するには、Expander コンポーネントで "プライベート フィールド" を使用して、切り替え状態を維持します。To maintain state in the preceding scenario, use a private field in the Expander component to maintain its toggled state.

次の変更された Expander コンポーネント:The following revised Expander component:

  • 親から Expanded コンポーネント パラメーター値を受け入れます。Accepts the Expanded component parameter value from the parent.
  • コンポーネント パラメーター値を、OnInitialized イベント の "プライベート フィールド" (expanded) に割り当てます。Assigns the component parameter value to a private field (expanded) in the OnInitialized event.
  • プライベート フィールドを使用して、内部のトグル状態を維持します。Uses the private field to maintain its internal toggle state.
<div @onclick="@Toggle" class="card bg-light mb-3" style="width:30rem">
    <div class="card-body">
        <h2 class="card-title">Toggle (<code>expanded</code> = @expanded)</h2>

        @if (expanded)
        {
            <p class="card-text">@ChildContent</p>
        }
    </div>
</div>

@code {
    private bool expanded;

    [Parameter]
    public bool Expanded { get; set; }

    [Parameter]
    public RenderFragment ChildContent { get; set; }

    protected override void OnInitialized()
    {
        expanded = Expanded;
    }

    private void Toggle()
    {
        expanded = !expanded;
    }
}

属性を適用するApply an attribute

属性は、@attribute ディレクティブを使用して Razor コンポーネントに適用できます。Attributes can be applied to Razor components with the @attribute directive. 次の例では、[Authorize] 属性をコンポーネント クラスに適用しています。The following example applies the [Authorize] attribute to the component class:

@page "/"
@attribute [Authorize]

条件付き HTML 要素属性Conditional HTML element attributes

HTML 要素属性は、.NET 値に基づいて条件付きでレンダリングされます。HTML element attributes are conditionally rendered based on the .NET value. 値が false または null の場合、属性はレンダリングされません。If the value is false or null, the attribute isn't rendered. 値が true の場合、属性が最小化されてレンダリングされます。If the value is true, the attribute is rendered minimized.

次の例では、IsCompleted によって checked が要素のマークアップにレンダリングされるかどうかを決定します。In the following example, IsCompleted determines if checked is rendered in the element's markup:

<input type="checkbox" checked="@IsCompleted" />

@code {
    [Parameter]
    public bool IsCompleted { get; set; }
}

IsCompletedtrue の場合、このチェック ボックスは次のようにレンダリングされます。If IsCompleted is true, the check box is rendered as:

<input type="checkbox" checked />

IsCompletedfalse の場合、このチェック ボックスは次のようにレンダリングされます。If IsCompleted is false, the check box is rendered as:

<input type="checkbox" />

詳細については、「ASP.NET Core の razor 構文リファレンス」を参照してください。For more information, see ASP.NET Core の razor 構文リファレンス.

警告

.NET 型が bool の場合、aria-pressed などの一部の HTML 属性が正しく機能しません。Some HTML attributes, such as aria-pressed, don't function properly when the .NET type is a bool. そのような場合は、bool ではなく string 型を使用します。In those cases, use a string type instead of a bool.

生 HTMLRaw HTML

通常、文字列は DOM テキスト ノードを使用してレンダリングされます。つまり、それらに含まれている可能性のあるすべてのマークアップが無視され、リテラル テキストとして扱われます。Strings are normally rendered using DOM text nodes, which means that any markup they may contain is ignored and treated as literal text. 生 HTML をレンダリングするには、HTML コンテンツを MarkupString 値にラップします。To render raw HTML, wrap the HTML content in a MarkupString value. 値は HTML または SVG として解析され、DOM に挿入されます。The value is parsed as HTML or SVG and inserted into the DOM.

警告

信頼されていないソースから構築された生 HTML をレンダリングすることは、セキュリティ リスクであるため、避ける必要があります。Rendering raw HTML constructed from any untrusted source is a security risk and should be avoided!

次の例では、MarkupString 型を使用して、コンポーネントのレンダリングされた出力に静的 HTML コンテンツのブロックを追加しています。The following example shows using the MarkupString type to add a block of static HTML content to the rendered output of a component:

@((MarkupString)myMarkup)

@code {
    private string myMarkup = 
        "<p class='markup'>This is a <em>markup string</em>.</p>";
}

Razor テンプレートRazor templates

レンダリング フラグメントは、Razor テンプレート構文を使用して定義できます。Render fragments can be defined using Razor template syntax. Razor テンプレートは、UI スニペットを定義する 1 つの方法であり、次の形式を想定しています。Razor templates are a way to define a UI snippet and assume the following format:

@<{HTML tag}>...</{HTML tag}>

次の例では、RenderFragmentRenderFragment<TValue> の値を指定し、コンポーネント内にテンプレートを直接レンダリングする方法を示しています。The following example illustrates how to specify RenderFragment and RenderFragment<TValue> values and render templates directly in a component. レンダリング フラグメントは、引数としてテンプレート コンポーネントに渡すこともできます。Render fragments can also be passed as arguments to templated components.

@timeTemplate

@petTemplate(new Pet { Name = "Rex" })

@code {
    private RenderFragment timeTemplate = @<p>The time is @DateTime.Now.</p>;
    private RenderFragment<Pet> petTemplate = (pet) => @<p>Pet: @pet.Name</p>;

    private class Pet
    {
        public string Name { get; set; }
    }
}

前のコードのレンダリングされた結果:Rendered output of the preceding code:

<p>The time is 10/04/2018 01:26:52.</p>

<p>Pet: Rex</p>

静的な資産Static assets

Blazor は、プロジェクトの web root (wwwroot) フォルダーに静的アセットを配置する ASP.NET Core アプリの規則に従います。Blazor follows the convention of ASP.NET Core apps placing static assets under the project's web root (wwwroot) folder.

静的アセットの Web ルートを参照するには、ベース相対パス (/) を使用します。Use a base-relative path (/) to refer to the web root for a static asset. 次の例では、logo.png が物理的に {PROJECT ROOT}/wwwroot/images フォルダーに配置されています。In the following example, logo.png is physically located in the {PROJECT ROOT}/wwwroot/images folder:

<img alt="Company logo" src="/images/logo.png" />

Razor コンポーネントでは、チルダ スラッシュ表記 (~/) はサポートされていませんRazor components do not support tilde-slash notation (~/).

アプリのベース パスの設定の詳細については、「ASP.NET Core Blazor のホストと展開」を参照してください。For information on setting an app's base path, see ASP.NET Core Blazor のホストと展開.

タグ ヘルパーはコンポーネントでサポートされないTag Helpers aren't supported in components

Tag Helpers は、Razor コンポーネント (.razor ファイル) ではサポートされていません。Tag Helpers aren't supported in Razor components (.razor files). Blazor にタグ ヘルパーのような機能を提供するには、タグ ヘルパーと同じ機能を持つコンポーネントを作成し、代わりにそのコンポーネントを使用します。To provide Tag Helper-like functionality in Blazor, create a component with the same functionality as the Tag Helper and use the component instead.

スケーラブル ベクター グラフィックス (SVG) イメージScalable Vector Graphics (SVG) images

Blazor では HTML がレンダリングされるため、スケーラブル ベクター グラフィックス (SVG) 画像 (.svg) などのブラウザーでサポートされている画像は、<img> タグを介してサポートされます。Since Blazor renders HTML, browser-supported images, including Scalable Vector Graphics (SVG) images (.svg), are supported via the <img> tag:

<img alt="Example image" src="some-image.svg" />

同様に、SVG 画像は、スタイルシート ファイル (.css) の CSS 規則でサポートされています。Similarly, SVG images are supported in the CSS rules of a stylesheet file (.css):

.my-element {
    background-image: url("some-image.svg");
}

ただし、インライン SVG マークアップは、すべてのシナリオでサポートされているわけではありません。However, inline SVG markup isn't supported in all scenarios. <svg> タグをコンポーネント ファイル (.razor) に直接配置した場合、基本的な画像レンダリングはサポートされますが、多くの高度なシナリオはまだサポートされていません。If you place an <svg> tag directly into a component file (.razor), basic image rendering is supported but many advanced scenarios aren't yet supported. たとえば、<use> タグは現在考慮されないため、一部の SVG タグで @bind を使用できません。For example, <use> tags aren't currently respected, and @bind can't be used with some SVG tags. 詳細については、Blazor の SVG サポート (dotnet/aspnetcore #18271)に関する記事を参照してください。For more information, see SVG support in Blazor (dotnet/aspnetcore #18271).

その他のリソースAdditional resources