实际项目当中经常会有很多重复使用的组件,她们具有相同的布局,只是填充的内容不一样,如果不停的复制粘贴也是件费劲的事情,而且也不好维护和更新,这时候就可以考虑使用模板化组件。
比如以下Bootstrap自带的Card组件:
红色框的部分就是公共的部分,我们可以把它们封装到模板化组件里。
1. RenderFragment
模板化组件需要用到RenderFragment类型的参数。对于上面的例子,我们可以分成Header和Body两个部分,如下:
@Header
@Body
@code { [Parameter] public RenderFragment Header { get; set; } [Parameter] public RenderFragment Body { get; set; }}1234567891011121314151617
调用的时候可以这样写:
Featured12345678910
RenderFragment 不仅可以使用静态内容,还可以使用Razor语法,如下:
Featured@foreach (var item in this.Items) { } @code { string[] Items = new string[] { "Cras justo odio","Dapibus ac facilisis in","Vestibulum at eros" };}1234567891011121314151617
你还可以把Items封装到Card组件里面:
@Header
@foreach (var item in this.Items) {
@item
}
@code { [Parameter] public RenderFragment Header { get; set; } [Parameter] public IEnumerable Items { get; set; }}1234567891011121314151617181920
调用如下:
Featured12345
2. RenderFragment
RenderFragment还可以带一个类型参数,这个参数有什么用呢? 看下面的例子:
@Header
@foreach (var item in this.Items) { @ItemTemplate(item) }
@code { [Parameter] public RenderFragment Header { get; set; } [Parameter] public RenderFragment ItemTemplate { get; set; } [Parameter] public IEnumerable Items { get; set; }}1234567891011121314151617181920212223
这里的ItemTemplate定义成了string类型的RenderFragment,并通过@ItemTemplate(item)来呈现内容,似乎有点不太好理解,先来看看调用方式:
Featured12345678
与前面的例子一样,ItemTemplate可以包含静态内容,也可以使用Razor语法,但是它多了一个@context,这个@context的类型其实就是参数声明里的string,她的值就是foreach里面当前item的值。
3. typeparam
RenderFragment 不仅可以使用固定类型,还可以通过typeparam来声明为泛型,如下:
@typeparam TItem
@Header
@foreach (var item in this.Items) { @ItemTemplate(item) }
@code { [Parameter] public RenderFragment Header { get; set; } [Parameter] public RenderFragment ItemTemplate { get; set; } [Parameter] public IEnumerable Items { get; set; }}12345678910111213141516171819202122232425
与前面的例子的区别就是string换成了TItem, 同时声明了@typeparam,这样我们就可以使用任意类型的列表了,如下:
Featured@code { Dictionary Users = new Dictionary() { { 1, "Cras justo odio" }, { 2, "Dapibus ac facilisis in" }, { 3, "Vestibulum at eros" } };}12345678910111213141516
由于这里传递的是Dictionary,所以@context就是KeyValuePair(因为Dictionary就是IEnumerable的实现)。
4 context
通过前面的例子我们已经可以知道@context其实就是RenderFragment中使用的类型,Blazor通过隐式的方式把当前的值传给了她。当然你也可以换成其他的名字,比如:
12345
通过Context属性,就可以将context修改成你想要的名字。
虽然这里的Context属性你可以放在ItemTemplate标签中,也可以放在Card标签中,但是笔者建议只放在ItemTemplate,以将修改控制在最小范围。
Cras justo odio
Dapibus ac facilisis in
Vestibulum at eros
@item
@context
@context.Value
@user.Value