Blazor 是否有一些像 vue 中的 $attrs 一样工作的机制?

Does Blazor have some mechanism working like $attrs in vue?

发现vue中的$attrs在组件设计中是一个很有帮助的东西。如果我有一个包装 "a" 标签的组件,我可以使用 $attrs 传递所有这些原生道具,而无需将它们一一声明为参数。例如,我有一个这样的组件:

<div>
    <a href="@Href" onclick="@OnClick" class="@Classes" style="@Styles">@Content</a>
</div>

我必须声明 "Href, OnClick, Classes, Styles" 的参数等等。但是我们知道标签 "a" 有大量的其他属性,比如 "target, hreflang...",更不用说 "input" 标签等等。我认为将它们全部声称为令人难以置信的长参数列表是愚蠢的。

那么 Blazor 是否为我们开发人员提供了类似的功能?

是的,确实如此。

您可以使用 Blazor 的新 ‘splat’ operator 来执行此操作。例如:

// MyComp

<div id=“@Id” @attributes=“InputAttributes”></div>

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

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

根据上面的示例定义一个参数将使其收集组件上定义的任何与任何现有声明参数不匹配的属性。

用法:

<MyComp Id=“foo” class=“myclass” />

将呈现:

<div id=“foo” class=“myclass”></div>

是的,来自 ASP.NET blog

#Accepting arbitrary parameters To define a component that accepts arbitrary attributes define a component parameter using the [Parameter] attribute with the CaptureUnmatchedValues property set to true. The type of the parameter must be assignable from Dictionary<string, object>. This means that IEnumerable<KeyValuePair<string, object>> or IReadOnlyDictionary<string, object> are also options.

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

The CaptureUnmatchedValues property on [Parameter] allows that parameter to match all attributes that do not match any other parameter. A component can only define a single parameter with CaptureUnmatchedValues.

Using @attributes to render arbitrary attributes

A component can pass arbitrary attributes to another component or markup element using the @attributes directive attribute. The @attributes directive allows you to specify a collection of attributes to pass to a markup element or component. This is valuable because the set of key-value-pairs specified as attributes can come from a .NET collection and do not need to be specified in the source code of the component.

<input class="form-field" @attributes="Attributes" type="text" />

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

Using the @attributes directive the contents of the Attribute property get “splatted” onto the input element. If this results in duplicate attributes, then evaluation of attributes occurs from left to right. In the above example if Attributes also contained a value for class it would supersede class="form-field". If Attributes contained a value for type then that would be superseded by type="text".