Как я могу случайным образом добавить атрибуты CSS к компоненту Blazor из родительского слоя, как это сделал Vue?

Поскольку я хочу разработать несколько многоразовых компонентов Blazor, я надеюсь, что у них может быть такая функция:

Предположим, у меня есть собственный компонент MyComponent, я могу добавить к нему любой атрибут CSS, когда я его использую:

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

Находясь в MyComponent, я обычно исправляю некоторые общие атрибуты CSS для верхнего слоя, вот так:

<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 и всеми присущими ему компонентами, но я все равно не могу избежать написания одного и того же комбинированного кода в каждом из них. Я надеюсь, что есть какое-то решение для добавления этих настраиваемых CSS непосредственно в мой базовый класс, я думаю, я мог бы добиться этого, переопределив метод BuildRenderTree из ComponentBase clss:

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

Но, к сожалению, я перепробовал все свои способы сборки вручную, но понятия не имею, как это сделать. Я не знаю, как получить элементы моего HTML (например, div) и добавить к нему дополнительные атрибуты CSS.

Все это о функции, которую легко может сделать Vue. В коде Vue мы, безусловно, могли бы добавить любой атрибут к компоненту и передать их первому элементу в компоненте.

Может ли кто-нибудь помочь мне в достижении этой цели или дать мне какое-то предложение?


person SillyJumper    schedule 05.07.2019    source источник
comment
Могу я спросить, почему использование шаблона, который вы определили для базового класса, не решает вашу проблему? Вам нужно будет использовать только @Classes, чтобы применить комбинированный CSS. Фактически, это именно то, что команда Blazor использует, чтобы разрешить настраиваемые классы CSS в элементах управления вводом формы.   -  person Chris Sainty    schedule 05.07.2019
comment
Прошу прощения, возможно, я не описал свою точку зрения четко, я хочу применить этот шаблон ко всем своим компонентам, а это означает, что мне приходится повторять один и тот же код комбинирования снова и снова (за исключением свойства Class), и это некрасиво.   -  person SillyJumper    schedule 08.07.2019


Ответы (4)


Я думаю, что ваш подход хорош, ему просто нужна небольшая абстракция, чтобы сделать его читабельным и легко управляемым для нескольких компонентов.

Вот почему я создал эту простую библиотеку вспомогательных функций. Это именно то, что вы делаете в своем коде, но предлагает API для согласованности.

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

person Ed Charbeneau    schedule 05.07.2019
comment
Спасибо, я внимательно рассмотрю предложение. - person SillyJumper; 08.07.2019
comment
Большой! Это именно то, что я хочу, и многое другое, спасибо за ваш вклад. - person SillyJumper; 08.07.2019

Насколько мне известно, прямо сейчас Blazor не предлагает встроенного способа обработки CSS, а лучшие практики и шаблоны Blazor еще не доступны, поэтому вы можете обрабатывать CSS любым подходящим способом, включая JSInterop.

Ниже приведена ссылка на библиотеку, которая, как мне кажется, может быть вам очень полезна: https://github.com/chanan/BlazorStyled

Надеюсь это поможет...

person enet    schedule 05.07.2019
comment
Спасибо, этот пакет дал мне другой образ мышления, это полезно. - person SillyJumper; 08.07.2019

попробуйте это, я использовал его, и он работает и прост

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

Я не уверен, что это плохая практика,

Это мешает itellisense правильно работать в атрибуте класса,
но это легко работает, просто добавьте его последним и в конце атрибута
, если вам нужно внести изменения с помощью intellisense, добавьте "" перед @ (класс), внесите изменения и удалите ""

он может оставить пробел в строке класса, если параметр Class не установлен в компоненте
например <div class="fixed-css1 fixed-css2 "> (пробел в конце)

person Scott    schedule 29.11.2019
comment
Спасибо, я решил это так же, как и вы. Добрый день. - person SillyJumper; 13.01.2020

Сделать это можно двумя способами.

Первый способ - использовать словарь для перехода от родителя к потомку, как показано ниже. В этом примере я добавил атрибут 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 на true. и напрямую передавать атрибут типа 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/gClG243kn1o и https://www.pragimtech.com/blog/blazor/blazor-arbitrary-attributes/

person vivek nuna    schedule 04.04.2021