簡體   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