能否解释一下Blazor组件标签的各种语法?

7
在我的 .razor 文件中,我有这些标记(仅作为示例)。它们可以工作,但是我无法解释各种语法背后的原因。
<HxButton Text=@StartButtonText OnClick="StartClick" Color="ThemeColor.Primary"/>
        
<Listener @ref=_listener/>
    
<button  @onclick=Show>Modal</button>

具体来说

  • 为什么有些标签的名称以 @ 开头(例如ref和onclick),而其他标签则没有。
  • 为什么ThemeColor.Primary用引号括起来,而StartButtonText没有。
  • 为什么StartButtonText前面有一个 @ 符号。
  • 为什么按钮的 @ onclick 属性是普通文本(不是@Show或"Show")。

我讨厌每次随机地遍历语法以找到可用的一种。

注意,HxButton来自HAVIT组件库,Listener是我基于HAVIT HxModal构建的组件。


Razor文件会被编译成C#类。你提出的语义问题是关于如何确保Razor预编译器按照你想要的方式解释你的Razor代码,主要是如何区分Html属性和组件属性/参数?@HenkHolterman在下面的回答中详细讨论了这些问题。 - MrC aka Shaun Curtis
我在这里找到了一个很好的解释:https://blazor-university.com/components/literals-expressions-and-directives/ - pm100
2个回答

8

Blazor是C#和HTML两种语言的交汇点,此外在某些情况下,这两种语言都可以使用多个语法变体。

  • 为什么有些标签名称前面有 @ 符号(比如 ref 和 onclick),而有些没有。

指令属性(例如 @ref@key@onclick 等)需要在名称前加上 @ 来表示它们是 C# 代码。这是必需的,因为这些属性通常有 HTML/JS 对应物,且它们以小写字母开头。

如果一个组件定义了一个参数,则不需要 @,但允许使用。在 Blazor 的最初版本中需要加上。

其他所有内容都传递给 HTML/JS。

  • 为什么 ThemeColor.Primary 中有引号,但 StartButtonText 没有。

StartButtonText 最好也加上引号,但在 HTML 中这是一种宽容态度。Text="@StartButtonText" 是推荐的写法。

  • 为什么 StartButtonText 带有 @ 符号。

这是 Blazor(Razor 语法)的主要“开关”。如果没有 @,屏幕上会显示字符串“StartButtonText”。加上 @ 后,它就成为一个 C# 变量的名称。与 @foreach() {...} 中的 @ 相同。

当期望使用委托(方法)时,允许但不需要使用 @

  • 为什么按钮的 @onclick 没有使用 @Show 或 "Show"。

此时已经清楚了 Show 必须是一个 C# 方法。如果不是,就会出现错误。没有必要使用 @ 来切换语言。但是 C# 允许在任何名称前面使用 @。这是一种转义规则,可以使用保留字,如 int @int = 3;,但也允许使用未保留的单词。使用 Show 或者 "Show" 再次说明了 HTML 的宽容性。

推荐写法是 @onclick="Show"


具体来说,关于Text=@StartButtonText和字符串参数,Text将在组件中声明为[Parameter]public string Text {get; set;}。如果你写成Text="StartButtonText",你传递给它的是一个字符串"StartButtonText":Razor预编译器不知道区别。要告诉预编译器你实际上想使用C#变量,你需要使用@前缀。几乎其他所有东西都无关紧要:在Count=myCounterProperty中,其中Count是一个intmyCounterProperty不能被解释为其他方式,所以预编译器会正确处理。 - MrC aka Shaun Curtis
@enet 如果您提供完整的答案,那将会更有帮助,因为这样更容易阅读。此外,它也可以被标记为正确答案。 - pm100

2
首先需要区分的是Razor组件标签和HTML标签。例如,为了解释HxButton组件中的OnClick是什么以及如何与button标签中的@onclick进行比较。因此,让我稍微详细介绍一下这个问题和其他相关困难,以便让困惑的读者更好地理解主题。
HxButton是一个Razor组件,它有一个名为OnClick的参数属性,已经赋值为"StartClick",这是在父组件中定义的方法的名称。该方法可能具有参数。 HxButton组件的父容器
<HxButton OnClick="StartClick"/>

@code
{
   private void StartClick (string value)
   {

   } 
}

在HxButton组件的定义中确定了参数的数量和类型。下面是组件中OnClick参数属性的定义:
[Parameter] public EventCallback<string> OnClick {get; set;} 

请注意,此事件“delegate”封装了一个具有单个字符串类型参数的方法。当在HxButton组件内执行此委托时,例如:OnClick.InvokeAsync(value);,将调用分配给OnClick参数属性的StartClick方法,在实例化HxButton时传递一个字符串值。
OnClick被定义为一个属性,编译器没有困难看到它。按钮HTML标记中的@onclick是一个编译器指令属性。它指示编译器分配给该属性的值应该是在触发按钮元素的click事件时调用的方法。它还告诉编译器在幕后创建一个EventCallback“delegate”的事件回调来表示回调方法。
但您可以使用这样的结构:onclick="alert('Hello')"。在这种情况下,onclick被编译器视为纯HTML属性,并且呈现为is。要区分这两种可能性,您必须指示编译器您想要做什么。因此是at“sign”的使用。顺便说一句,onclick =“alert('Hello')”,是纯JavaScript。
请注意:分配给OnClick参数属性的值是应评估为EventCallback的表达式,因此它可以是方法的名称,也可以是lambda表达式,例如: OnClick="@((value) => StartClick(value))" 还要注意,方法的名称可以以@符号开头,如下所示:OnClick="@StartClick"
当Blazor处于初始开发阶段时,这是必需的。现在不再需要了,但用户不强制不使用它。我花了一些时间才摆脱像这样使用它的习惯。如今,我总是跳过@符号。
总之,所有编译器指令属性都应以@符号开头,例如@ref @onclick @oninput等。
“为什么StartButtonText有@符号”
因为它是一个应评估为字符串值的表达式。首先,我建议您使用带引号的括号,例如: <HxButton Text="@StartButtonText" /> 注意:"@StartButtonText"是一个字符串插值表达式,它使得在HxButton组件上定义的Text属性和主机组件上定义的变量StartButtonText之间实现数据绑定。
请注意,您必须应用@符号,否则字符串Text属性将包含字符串StartButtonText,而不是变量StartButtonText中存储的值。

为什么ThemeColor.Primary要用引号括起来,而StartButtonText不用?

这个问题属于人性的范畴,或者说应该向Peter Morris提问,他的论文导致了不遵守统一性的混乱。我之所以特别提到他,是因为你提供了一个称为“好的解释”的链接。
无论如何,您可以像这样做:Color="ThemeColor.Primary" 或者像这样:Color="@ThemeColor.Primary" 或者像这样:Color=ThemeColor.Primary 或者像这样:Color=@ThemeColor.Primary
如果你问你的代码作者:为什么ThemeColor.Primary要用引号括起来,而StartButtonText不用?,他可能会试图归咎于人类的不一致性而不是自己的无能。
Visual Studio编辑器会自动插入双引号,您需要在其中提供一个值,这就是应该做的方式。个人喜好,正如Peter Morris所传授的那样,可能对社会不利。你的问题是一个好问题,因为它显示了同一行中这种荒谬的不一致性的存在:是的,为什么要将ThemeColor.Primary用引号括起来,而不是StartButtonText...

我喜欢Morrises的解释,但他的引用建议等并没有真正被我接受。HxButton行的作者是我,颜色部分来自于他们的文档,但他们使用了硬编码文本,我发现需要@XXX,并猜测了语法。 - pm100
这两个答案提供了一个历史解释,说明为什么多个 Blazor 组件声明选项会发展成这样,感谢 @enet 和 @HH 的详细解答。然而,未来在我的代码中将采用链接到早期的简化 Peter Morris 语法约定。 - camelCase

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接