DevGang
Авторизоваться

Создайте свою собственную библиотеку пользовательского интерфейса Vue с помощью Unstyled PrimeVue Core и Tailwind CSS

Обертывание компонентов пользовательского интерфейса для инкапсуляции настраиваемого поведения — распространенная практика при создании собственной библиотеки пользовательского интерфейса, особенно в более крупных командах, где общая библиотека используется среди множества приложений. Основным преимуществом этого подхода является отделение зависимости от сторонней библиотеки, поскольку приложения-потребители вместо этого зависят от общей библиотеки.

Нестилизованное ядро ​​PrimeVue и Tailwind CSS станут идеальным набором инструментов, если вам нужно создать собственную библиотеку пользовательского интерфейса. Основная идея состоит в том, чтобы создать компонент пользовательского интерфейса, обернув компонент PrimeVue, передать свои реквизиты как промежуточные и настроить сквозную предустановку Tailwind локально, а не глобальную конфигурацию.

Тумблер

Давайте создадим наш собственный компонент ToggleSwitch, вдохновленный Material Design. Для этого мы будем использовать компонент PrimeVue InputSwitch.

Шаблон

Раздел шаблона состоит из гибкого контейнера-оболочки, встроенной метки и PrimeVue InputSwitch. Обратите внимание на использование v-bind="$attrs", поскольку мы хотели бы применить любое свойство, переданное нашему собственному компоненту, к базовому InputSwitch, например, v-model и v-onсобытиям. Компонент здесь отвечает за основную функциональность и доступность, а мы фокусируемся на стандартизации требований к дизайну.

<template>
    <div class="flex items-center gap-4">
        <label :for="$attrs.inputId">{{ label }}</label>
        <InputSwitch v-bind="$attrs" />
    </div>
</template>

Скрипт

Скрипт устанавливает inheritAttrs значение false, в противном случае свойства падения применяются к основному элементу контейнера div. Дополнительные реквизиты, такие как метка, включены как реквизиты нашего собственного компонента.

Предварительные настройки

Итак, вся проводка на месте, пора применить наш собственный стиль, вдохновленный дизайном материалов, реализованных с помощью утилит Tailwind. Стиль применяется локально с помощью свойства InputSwitch, поскольку мы используем локальную предустановку, отключив слияние с глобальной предустановкой с помощью ptOptions. Для этого мы будем использовать пресет переключения материала из галереи пресетов CSS PrimeVue Tailwind.

<template>
    <div class="flex items-center gap-4">
        <label :for="$attrs.inputId">{{ label }}</label>
        <InputSwitch v-bind="$attrs" :pt="preset" :ptOptions="{ mergeSections: false, mergeProps: false }" />
    </div>
</template>

Предустановка представляет собой простую конфигурацию pt, основанную на API-интерфейсе InputSwitch PassThrough с некоторыми расширениями. Обратите внимание на использование attrs для добавления режима акцентов, которого нет в API PrimeVue InputSwitch. Мы можем использовать произвольные атрибуты для добавления функциональности к компонентам, которые мы обертываем, не дожидаясь, пока специалист по сопровождению библиотеки компонентов добавит это за нас. Это отличный пример философии PrimeVue, предоставляющей стороннюю библиотеку пользовательского интерфейса, которую легко настраивать, как если бы это была собственная библиотека.

<script setup>
defineOptions({
    inheritAttrs: false
});

defineProps(['label']);

const preset = {
    root: ({ props }) => ({
        class: [
            'inline-block relative',
            'w-10 h-4',
            {
                'opacity-40 select-none pointer-events-none cursor-default': props.disabled
            }
        ]
    }),
    slider: ({ props, state, attrs }) => ({
        class: [
            // Position
            'absolute top-0 left-0 right-0 bottom-0 before:transform',
            { 'before:translate-x-5': props.modelValue },
            { 'before:-translate-x-1': !props.modelValue },

            // Shape
            'rounded-2xl',

            // Before:
            'before:absolute before:top-1/2',
            'before:-mt-3',
            'before:h-6 before:w-6',
            'before:rounded-full',
            'before:duration-200',
            'before:flex before:justify-center before:items-center',
            'before:[text-shadow:0px_0px_WHITE] before:text-transparent',
            { 'before:ring-4': state.focused },
            {
                "before:bg-surface-500 before:dark:bg-surface-500 before:content-['➖']": !props.modelValue,
                "before:content-['✔️']": props.modelValue,
                'before:bg-violet-500 before:ring-violet-300': !attrs.type & props.modelValue,
                'before:bg-amber-500 before:ring-amber-300': attrs.type === 'accent' && props.modelValue
            },

            // Colors
            'border border-transparent',
            {
                'bg-surface-200 dark:bg-surface-400 before:ring-surface-200 dark:before:ring-surface-400': !props.modelValue,
                'bg-violet-300': !attrs.type & props.modelValue,
                'bg-amber-300': attrs.type === 'accent' && props.modelValue
            },

            // States
            {
                'hover:before:bg-surface-400 hover:dark:before:bg-surface-600': !props.modelValue,
                'hover:before:bg-violet-600': !attrs.type & props.modelValue,
                'hover:before:bg-amber-600': attrs.type === 'accent' && props.modelValue
            },

            // Transition
            'transition-colors duration-200',

            // Misc
            'cursor-pointer'
        ]
    })
};
</script>

Конечный результат

Давайте завершим это примером использования. Смотрите демонстрацию переключения материала, чтобы увидеть рабочий образец пресета, который мы использовали в этом компоненте.

<ToggleSwitch v-model="checked1" inputId="primary" label="Primary" />
<ToggleSwitch v-model="checked2" inputId="accent" label="Accent" type="accent" />

Источник:

#Vue.js
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться

Присоединяйся в тусовку

В этом месте могла бы быть ваша реклама

Разместить рекламу