繁体   English   中英

我如何像Vue那样从父层随机添加CSS属性到Blazor组件?

[英]How can I randomly add CSS attributes to Blazor component from parent layer as Vue did?

由于我想设计一些可重用的 Blazor 组件,我希望它们能够具有这样的功能:

假设我有一个自定义组件“MyComponent”,我可以在使用它时向它添加任何 CSS 属性:

<MyComponent Class="custom-css1 custom-css2">
    some child content...
</MyComponent>

在 MyComponent 中,我通常会像这样将一些常见的 CSS 属性固定到顶部 wapper:

<div class="fixed-css1 fixed-css2">
    some child content...
</div>

这意味着我必须将 CSS 属性的两个部分组合在一起,使最终的 HTML 如下所示:

<div class="fixed-css1 fixed-css2 custom-css1 custom-css2">
    some child content...
</div>

所以我想我应该有这个模式:

<div class="@Classes">
    some child content...
</div>

@functions
{

    [Parameter]
    private string Class { get; set; } = "";

    private string fixedClass = "fixed-css1 fixed-css2";

    private string Classes
    {
        get
        {
            return $"{fixedClass} {Class}";
        }
    }
}

为了减少冗余代码,我可以制作一个基数 class,它具有受保护的 Class 属性和它固有的每个组件,但我仍然无法避免在每个组件中编写相同的组合代码。 我希望有一些解决方案可以直接在我的基础 class 中添加这些自定义 CSS,我想我可以通过覆盖 ComponentBase 类的 BuildRenderTree 方法来实现:

protected override void BuildRenderTree(RenderTreeBuilder builder)
        {
            base.BuildRenderTree(builder);
        }

但不幸的是,我已经尝试了所有手动构建的方法,但不知道如何完成。 我不知道如何获取我的 HTML 的元素(例如“div”)并向其添加额外的 CSS 属性。

所有这些都是关于做Vue可以轻松完成的功能。 在 Vue 代码中,我们当然可以向组件添加任何属性并将它们传递给组件中的第一个元素。

任何人都可以帮助我完成这个目标或给我一些建议吗?

我认为您的方法很好,它只需要对其进行一些抽象,以使其具有可读性并且可以跨多个组件轻松管理。

这就是我创建这个简单的辅助函数库的原因。 这正是您在代码中所做的,但提供了一个 API 以确保一致性。

https://www.nuget.org/packages/BlazorComponentUtilities/

据我所知,目前,Blazor 不提供处理 CSS 的内置方法,而且 Blazor 最佳实践和模式尚不可用,因此您可以以任何您认为合适的方式处理 CSS,包括 JSI​​nterop。

以下是我认为对您非常有用的库的链接: https : //github.com/chanan/BlazorStyled

希望这可以帮助...

试试这个,我用过它,它有效而且很简单

<div class="fixed-css1 fixed-css2 @(Class)">
    some child content...
</div>

我不确定这是否是一种不好的做法,

它会阻止 itellisense 在 class 属性中正常工作,
但这很容易实现,只需将其添加到属性的最后和末尾即可
如果您需要使用智能感知进行更改,请在@(class) 之前添加一个“”,进行更改,然后删除“”

如果组件上没有设置 Class 参数,它可能会在类字符串中留一个空格
例如<div class="fixed-css1 fixed-css2 "> (末尾有空格)

您可以通过两种方式执行此操作。

第一种方法,您可以使用字典从父级传递给子级,如下所示。 我在这个例子中添加了required属性。

子组件:

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

@code {
    [Parameter]
    public Dictionary<string, object> InputAttributes { get; set; } = 
        new Dictionary<string, object>() 
        {
            { "placeholder", "Child Component Placeholder" }
        };
}

父组件:

<ChildComponent InputAttributes="attributesFromParent">
</ChildComponent>

@code {
    public Dictionary<string, object> attributesFromParent { get; set; } = 
        new Dictionary<string, object>() 
        {
            { "required", "required" },
            { "placeholder", "Parent Component Placeholder" }
        };
}

第二种方法,您可以通过将CaptureUnmatchedValues设置为truetrue 并直接将像maxlength这样的属性从父级传递给子级。

子组件:

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

@code {
    [Parameter(CaptureUnmatchedValues = true)]
    public Dictionary<string, object> InputAttributes { get; set; } = 
        new Dictionary<string, object>() 
        {
            { "placeholder", "Child Component Placeholder" }
        };
}

父组件:

<ChildComponent InputAttributes="attributesFromParent" maxlength="15">
</ChildComponent>

@code {
    public Dictionary<string, object> attributesFromParent { get; set; } = 
        new Dictionary<string, object>() 
        {
            { "required", "required" },
            { "placeholder", "Parent Component Placeholder" }
        };
}

参考: https : //youtu.be/gClG243kn1ohttps://www.pragimtech.com/blog/blazor/blazor-arbitrary-attributes/

假设:

  • 你想在父类中添加类
  • 你想在孩子中添加课程
  • 您希望所有类都合并到最终标记中
  • 您想使用class ... 而不是ClassClassesCssCssClass或其他什么!

ChildComponent.razor

<div @attributes=_additionalAttributes></div>

@code {

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

  private IReadOnlyDictionary<string, object>? _additionalAttributes;

  protected override void OnParametersSet()
  {
    base.OnParametersSet();

    var parentClasses = AdditionalAttributes.GetValueOrDefault("class", "");
    var classes       = $"foo {parentClasses}".Trim();

    _additionalAttributes = 
      AdditionalAttributes.Where(x => x.Key != "class")
      .Append(KeyValuePair.Create("class", (object)classes))
      .ToDictionary(x => x.Key, x => x.Value);
  }

}

ParentComponent.razor现在是干净的,具有正常名称class

<ChildComponent class="bar baz" />

@code {
}

哪个呈现:

<div class="foo bar baz"></div>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM