ASP.NET Core Blazor 屬性展開和任意參數

注意

這不是這篇文章的最新版本。 如需目前版本,請參閱本文的 .NET 8 版本

重要

這些發行前產品的相關資訊在產品正式發行前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。

如需目前版本,請參閱本文的 .NET 8 版本

除了元件所宣告的參數之外,元件還可以擷取和轉譯其他屬性。 您可以在字典中擷取其他屬性,然後在使用 @attributesRazor 指示詞屬性轉譯元件時,將擷取的屬性「展開」到元素上。 此案例適用於定義元件來產生支援各種自訂的標記元素。 例如,若要針對支援許多參數的 <input> 來個別定義屬性可能會很繁瑣。

屬性展開

在下列 Splat 元件中:

  • 第一個 <input> 元素 (id="useIndividualParams") 會使用個別的元件參數。
  • 第二個 <input> 元素 (id="useAttributesDict") 會使用屬性展開。

Splat.razor

@page "/splat"

<PageTitle>SPLAT!</PageTitle>

<h1>Splat Parameters Example</h1>

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

在網頁中轉譯的 <input> 元素完全相同:

<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

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

[Parameter] 上的 CaptureUnmatchedValues 屬性可讓參數比對不符合任何其他參數的所有屬性。 元件只能使用 CaptureUnmatchedValues 來定義單一參數。 搭配 CaptureUnmatchedValues 使用的屬性類型必須可透過 Dictionary<string, object> 使用字串索引鍵來指派。 在此案例中,也可以選擇使用 IEnumerable<KeyValuePair<string, object>>IReadOnlyDictionary<string, object>

@attributes 的位置相對於元素屬性的位置有其重要性。 在元素上展開 @attributes 時,會從右到左 (最後一個到第一個) 處理屬性。 請考慮下列會取用子元件的父元件範例:

AttributeOrderChild1.razor

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

@code {
    [Parameter(CaptureUnmatchedValues = true)]
    public IDictionary<string, object>? AdditionalAttributes { get; set; }
}
<div @attributes="AdditionalAttributes" extra="5" />

@code {
    [Parameter(CaptureUnmatchedValues = true)]
    public IDictionary<string, object>? AdditionalAttributes { get; set; }
}
<div @attributes="AdditionalAttributes" extra="5" />

@code {
    [Parameter(CaptureUnmatchedValues = true)]
    public IDictionary<string, object>? AdditionalAttributes { get; set; }
}
<div @attributes="AdditionalAttributes" extra="5" />

@code {
    [Parameter(CaptureUnmatchedValues = true)]
    public IDictionary<string, object> AdditionalAttributes { get; set; }
}
<div @attributes="AdditionalAttributes" extra="5" />

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

AttributeOrder1.razor

@page "/attribute-order-1"

<PageTitle>Attribute Order 1</PageTitle>

<h1>Attribute Order Example 1</h1>

<AttributeOrderChild1 extra="10" />

<p>
    View the HTML markup in your browser to inspect the attributes on
    the AttributeOrderChild1 component.
</p>

AttributeOrderParent1.razor

@page "/attribute-order-parent-1"

<AttributeOrderChild1 extra="10" />

AttributeOrderParent1.razor

@page "/attribute-order-parent-1"

<AttributeOrderChild1 extra="10" />

AttributeOrderParent1.razor

@page "/attribute-order-parent-1"

<AttributeOrderChild1 extra="10" />

AttributeOrderParent1.razor

@page "/attribute-order-parent-1"

<AttributeOrderChild1 extra="10" />

AttributeOrderChild1 元件的 extra 屬性會設定到 @attributes 的右邊。 AttributeOrderParent1 元件所轉譯的 <div> 在傳遞其他屬性時會包含 extra="5",因為屬性會從右到左 (最後一個到第一個) 進行處理:

<div extra="5" />

在下列範例中,extra@attributes 在子元件的 <div> 中的順序會顛倒:

AttributeOrderChild2.razor

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

@code {
    [Parameter(CaptureUnmatchedValues = true)]
    public IDictionary<string, object>? AdditionalAttributes { get; set; }
}
<div extra="5" @attributes="AdditionalAttributes" />

@code {
    [Parameter(CaptureUnmatchedValues = true)]
    public IDictionary<string, object>? AdditionalAttributes { get; set; }
}
<div extra="5" @attributes="AdditionalAttributes" />

@code {
    [Parameter(CaptureUnmatchedValues = true)]
    public IDictionary<string, object>? AdditionalAttributes { get; set; }
}
<div extra="5" @attributes="AdditionalAttributes" />

@code {
    [Parameter(CaptureUnmatchedValues = true)]
    public IDictionary<string, object> AdditionalAttributes { get; set; }
}
<div extra="5" @attributes="AdditionalAttributes" />

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

AttributeOrder2.razor

@page "/attribute-order-2"

<PageTitle>Attribute Order 2</PageTitle>

<h1>Attribute Order Example 2</h1>

<AttributeOrderChild2 extra="10" />

<p>
    View the HTML markup in your browser to inspect the attributes on
    the AttributeOrderChild2 component.
</p>

AttributeOrderParent2.razor

@page "/attribute-order-parent-2"

<AttributeOrderChild2 extra="10" />

AttributeOrderParent2.razor

@page "/attribute-order-parent-2"

<AttributeOrderChild2 extra="10" />

AttributeOrderParent2.razor

@page "/attribute-order-parent-2"

<AttributeOrderChild2 extra="10" />

AttributeOrderParent2.razor

@page "/attribute-order-parent-2"

<AttributeOrderChild2 extra="10" />

父元件所轉譯網頁中的 <div> 在傳遞其他屬性時會包含 extra="10"

<div extra="10" />