1. 参数(Parameter)
参数主要用来在各组件之间传递值,在初始项目的SurveyPrompt组件中就包含了一个参数:
[Parameter]
public string Title { get; set; }
通过用Parameter修饰符来修饰,就可以将指定的属性(注意要是public的)声明为参数,使用也很简单:
<SurveyPrompt Title="这里是参数的值" />
2. CaptureUnmatchedValues
我们来看看的定义Parameter的定义
public sealed class ParameterAttribute : Attribute
{
public ParameterAttribute();
public bool CaptureUnmatchedValues { get; set; }
}
她包含一个额外的属性CaptureUnmatchedValues,那么这个属性是干嘛用的呢?根据官方的解释,她可以用来接受任意数量的额外参数,而且修饰的属性必须要是字典类型:IDictionary<string,object>。
比如我添加一个组件ParmComp2.razor,代码如下:
<h3>Hello @NickName</h3>
@if (AdditionalInfo != null)
{
foreach(var kv in this.AdditionalInfo)
{
<p>@kv.Key:@kv.Value</p>
}
}
@code {
[Parameter]
public string NickName { get; set; }
[Parameter(CaptureUnmatchedValues =true)]
public IDictionary<string,object> AdditionalInfo { get; set; }
}
采用如下方式调用:
<ParmComp2 nickname="Bigname 65" age="36" gender="male"></ParmComp2>
我们来看看她的输出:
该参数自动接受了除NickName之外的另外两个参数age & gender。
除此之外我们还可以通过@attributes将该参数绑到任意的元素,比如:
<input @attributes="AdditionalInfo" />
如果这样调用:
<ParmComp2 type="text" width="200px" placeholder="please enter your name" maxlength="10"></ParmComp3>
她可以自动将所有参数代入组件里面的input元素,形成以下输出:
<input type="text" width="200px" placeholder="please enter your name" maxlength="10">
3. 级联参数(CascadingParameter)
级联参数看起来就比Parameter更高级,她主要用来在多级组件之间传递参数,听起来有点抽象,咱们举个栗子:
考虑以下三个组件的嵌套关系,如果想把一个参数同时传给CascComp1和CascComp2应该如何做呢?
如果采用普通的Parameter,代码应该是这样的:
<!--this is CascCompSample.razor-->
<h3>This is the sample page</h3>
<CascComp1 NickName="Bigname 65"></CascComp1>
<!--this is CascComp1.razor-->
<h3>Comp1: @NickName</h3>
<CascComp2 NickName="@NickName"></CascComp2>
@code {
[Parameter]
public string NickName { get; set; }
}
<!--this is CascComp2.razor-->
<h3>Comp2: @NickName</h3>
@code {
[Parameter]
public string NickName { get; set; }
}
采用CascadingParameter会有什么不一样呢?请看:
<!--this is CascCompSample.razor-->
@page "/cascparamsample"
<h3>This is the sample page</h3>
<CascadingValue Value="NickName">
<CascComp1></CascComp1>
</CascadingValue>
@code
{
private string NickName = "Bigname65";
}
<!--this is CascComp1.razor-->
<h3>Comp1: @NickName</h3>
<CascComp2></CascComp2>
@code {
[CascadingParameter]
public string NickName { get; set; }
}
<!--this is CascComp2.razor-->
<h3>Comp2: @NickName</h3>
@code {
[CascadingParameter]
public string NickName { get; set; }
}
看到区别了吗?
- 首先在CascCompSample.razor页面,我们通过把CascComp1嵌套到CascadingValue里面来传递参数。
- 其次在CascComp1和CascComp2,不再需要显式传递参数,只需要声明CascadingParameter即可拿到值。
CascadingValue组件的Value参数不能直接传递字符串,必须要声明一个变量
那么什么场景下需要用到这种方式呢?我想比较多的还是用来在多个组件之间共享上下文吧。
4. CascadingParameter如何传递多个参数
前面的例子我们通过CascadingParameter传递了一个参数,那么有没有办法传递多个参数呢?
当然可以,CascadingValue是支持嵌套的,你可以这样:
<!--this is CascCompSample.razor-->
@page "/cascparamsample"
<h3>This is the sample page</h3>
<CascadingValue Value="NickName">
<CascadingValue Value="36">
<CascComp1></CascComp1>
</CascadingValue>
</CascadingValue>
@code
{
private string NickName = "Bigname65";
}
<!--this is CascComp1.razor-->
<h3>Comp1: @NickName - @Age</h3>
<CascComp2></CascComp2>
@code {
[CascadingParameter]
public string NickName { get; set; }
[CascadingParameter]
public int Age { get; set; }
}
看到这里你肯定会有疑问,参数之间到底是如何关联上的呢?
其实Blazor是通过参数的类型来关联的,在外层通过CascadingValue传递了一个字符串和一个整数,在里层则通过类型匹配将字符串赋值给NickName,将整数赋值给Age。所以里层的参数名是可以随便取的,你可以把NickName改为FullName,并不会影响参数值的获取。
这个方式虽然可以少写一些代码,但是容易出错,而且如果碰到多个同类型的参数就无法处理了,笔者并不建议用这种方式。
除此之外,CascadingValue还有一个Name参数,可以给每个参数指定参数名,这样就可以显式的把各个组件的参数关联起来,笔者建议不管是一个参数还是多个参数都指定一个名字,这样可以尽量避免混淆,代码如下:
<!--this is CascCompSample.razor-->
@page "/cascparamsample"
<h3>This is the sample page</h3>
<CascadingValue Value="NickName" Name="NickName">
<CascadingValue Value="36" Name="Age">
<CascComp1></CascComp1>
</CascadingValue>
</CascadingValue>
@code
{
private string NickName = "Bigname65";
}
<!--this is CascComp1.razor-->
<h3>Comp1: @NickName - @Age</h3>
<CascComp2></CascComp2>
@code {
[CascadingParameter(Name="NickName")]
public string NickName { get; set; }
[CascadingParameter(Name="Age")]
public int Age { get; set; }
}
需要注意的是如果在CascadingValue组件里面指定了Name参数,那么在所有CascadingParameter的地方也需要指定Name,否则就会找不到参数值