Tailwind CSS

PrimeVue 和 Tailwind CSS 在样式和无样式模式下的集成。

Tailwind CSS 是一个流行的 CSS 框架,基于实用优先的设计。核心提供灵活的 CSS 类,具有预定义的 CSS 规则,用于构建您自己的 UI 元素。例如,与 Bootstrap 中的意见化的 btn 类不同,Tailwind 提供了 bg-blue-500roundedp-4 等原始类来应用按钮。一组可重用的类也可以组合成一个 Tailwind CSS 组件,甚至有一些库采用这种方法来构建专门针对 Tailwind 的组件。

Tailwind 是一个出色的 CSS 库,但与 Vue.js 结合使用时,它缺乏一个真正的综合 UI 套件,这就是 PrimeVue 提供广泛的、高度可访问的、功能丰富的 UI 组件库的原因。PrimeVue 的核心不依赖于 Tailwind CSS,而是我们提供了必要的集成点,例如 primeui tailwind 插件和无样式模式的预设。

在 PrimeVue 的无样式模式下,默认样式元素(如设计令牌和 css 类)被关闭,因此您可以通过直通属性完全控制组件的样式。当您想要通过包装 PrimeVue 组件来构建基于自定义设计的 UI 库,或者只是使用 Tailwind CSS 来样式化 PrimeVue 组件时,此功能非常有用。

无样式模式还像样式模式一样使用 preset 概念来定义主题。在样式模式下,预设是使用 CSS 变量实现的一组设计令牌,而在无样式模式下,预设是将 Tailwind CSS 类注入组件的直通配置对象。如果您希望忽略默认的样式模式主题化 api 并改用 Tailwind CSS 来样式化 PrimeVue UI 组件,请在独立的 Tailwind CSS 预设 项目网站上了解更多信息。

tailwindcss-primeui 是 PrimeTek 提供的官方插件,用于在 Prime UI 库(如 PrimeVue)和 Tailwind CSS 之间提供一流的集成。它旨在同时在样式和无样式模式下工作。例如,在样式模式下,语义颜色(如 primary 和 surfaces)被提供为 Tailwind 工具 e.g. bg-primary, text-surface-500, text-muted-color.

插件在 npm 上可用。


npm i tailwindcss-primeui

安装后,在您的 tailwind 配置文件中配置插件。


// tailwind.config.js
module.exports = {
    // ...
    plugins: [require('tailwindcss-primeui')]
};

该插件使用一组新的工具扩展了默认配置。所有变体和断点都受支持,例如 dark:sm:hover:bg-primary

颜色调色板

属性
primary-[50-950]主要颜色调色板。
surface-[0-950]表面颜色调色板。
primary默认主要颜色。
primary-contrast默认主要对比色。
primary-emphasis默认主要强调色。
border-surface默认主要强调色。
bg-emphasis强调背景,例如悬停元素。
bg-highlight突出显示背景。
bg-highlight-emphasis带有强调的突出显示背景。
rounded-border边框半径。
text-color带有强调的文本颜色。
text-color-emphasis默认主要强调色。
text-muted-color次要文本颜色。
text-muted-color-emphasis带有强调的次要文本颜色。

在样式模式下,Tailwind 工具可能无法覆盖默认样式,因为 CSS 特定性,有两种可能的解决方案。

重要

使用 ! 作为前缀以强制执行样式。


<InputText placeholder="Overriden" class="!p-8" />

CSS 层

启用 PrimeVue CSS 层,并将 tailwind 样式配置为具有更高特定性(通过分层)。这样,就不需要 ! 前缀。


import PrimeVue from 'primevue/config';
import Aura from '@primevue/themes/aura';

const app = createApp(App);

app.use(PrimeVue, {
    theme: {
        preset: Aura,
        options: {
            cssLayer: {
                name: 'primevue',
                order: 'tailwind-base, primevue, tailwind-utilities'
            }
        }
    }
 });


@layer tailwind-base, primevue, tailwind-utilities;

@layer tailwind-base {
  @tailwind base;
}

@layer tailwind-utilities {
  @tailwind components;
  @tailwind utilities;
}

使用 PrimeVue 和 Tailwind CSS 的示例用例。

PrimeVue 颜色调色板作为工具类。

  • primary
    50
    100
    200
    300
    400
    500
    600
    700
    800
    900
    950
  • surface
    0
    50
    100
    200
    300
    400
    500
    600
    700
    800
    900
    950
primary
highlight
box

使用 Tailwind 工具来响应式布局具有 PrimeVue 组件的表单。


<div class="flex flex-col gap-6 w-full sm:w-auto">
    <div class="flex flex-col sm:flex-row sm:items-center gap-6">
        <div class="flex-auto">
            <label for="firstname" class="block font-semibold mb-2">Firstname</label>
            <InputText id="firstname" class="w-full" />
        </div>
        <div class="flex-auto">
            <label for="lastname" class="block font-semibold mb-2">Lastname</label>
            <InputText id="lastname" class="w-full" />
        </div>
    </div>
    <div class="flex flex-col sm:flex-row sm:items-center gap-6">
        <div class="flex-1">
            <label for="date" class="block font-semibold mb-2">Date</label>
            <DatePicker inputId="date" class="w-full" />
        </div>
        <div class="flex-1">
            <label for="country" class="block font-semibold mb-2">Country</label>
            <Select v-model="selectedCountry" inputId="country" :options="countries" optionLabel="name" placeholder="Select a Country" class="w-full">
                <template #value="slotProps">
                    <div v-if="slotProps.value" class="flex items-center">
                        <img :alt="slotProps.value.label" src="https://primefaces.org/cdn/primevue/images/flag/flag_placeholder.png" :class="`mr-2 flag flag-${slotProps.value.code.toLowerCase()}`" style="width: 18px" />
                        <div>{{ slotProps.value.name }}</div>
                    </div>
                    <span v-else>
                        {{ slotProps.placeholder }}
                    </span>
                </template>
                <template #option="slotProps">
                    <div class="flex items-center">
                        <img :alt="slotProps.option.label" src="https://primefaces.org/cdn/primevue/images/flag/flag_placeholder.png" :class="`mr-2 flag flag-${slotProps.option.code.toLowerCase()}`" style="width: 18px" />
                        <div>{{ slotProps.option.name }}</div>
                    </div>
                </template>
            </Select>
        </div>
    </div>
    <div class="flex-auto">
        <label for="message" class="block font-semibold mb-2">Message</label>
        <Textarea id="message" class="w-full" rows="4" />
    </div>
</div>

具有自定义 UI 的无头 PrimeVue 对话框。


<Button label="Login" icon="pi pi-user" @click="visible = true" />

<Dialog v-model:visible="visible" pt:root:class="!border-0 !bg-transparent" pt:mask:class="backdrop-blur-sm">
    <template #container="{ closeCallback }">
        <div class="flex flex-col px-8 py-8 gap-6 rounded-2xl" style="background-image: radial-gradient(circle at left top, var(--p-primary-400), var(--p-primary-700))">
            <svg width="35" height="40" viewBox="0 0 35 40" fill="none" xmlns="http://www.w3.org/2000/svg" class="block mx-auto">
                <path
                    d="M25.87 18.05L23.16 17.45L25.27 20.46V29.78L32.49 23.76V13.53L29.18 14.73L25.87 18.04V18.05ZM25.27 35.49L29.18 31.58V27.67L25.27 30.98V35.49ZM20.16 17.14H20.03H20.17H20.16ZM30.1 5.19L34.89 4.81L33.08 12.33L24.1 15.67L30.08 5.2L30.1 5.19ZM5.72 14.74L2.41 13.54V23.77L9.63 29.79V20.47L11.74 17.46L9.03 18.06L5.72 14.75V14.74ZM9.63 30.98L5.72 27.67V31.58L9.63 35.49V30.98ZM4.8 5.2L10.78 15.67L1.81 12.33L0 4.81L4.79 5.19L4.8 5.2ZM24.37 21.05V34.59L22.56 37.29L20.46 39.4H14.44L12.34 37.29L10.53 34.59V21.05L12.42 18.23L17.45 26.8L22.48 18.23L24.37 21.05ZM22.85 0L22.57 0.69L17.45 13.08L12.33 0.69L12.05 0H22.85Z"
                    fill="var(--p-primary-700)"
                />
                <path
                    d="M30.69 4.21L24.37 4.81L22.57 0.69L22.86 0H26.48L30.69 4.21ZM23.75 5.67L22.66 3.08L18.05 14.24V17.14H19.7H20.03H20.16H20.2L24.1 15.7L30.11 5.19L23.75 5.67ZM4.21002 4.21L10.53 4.81L12.33 0.69L12.05 0H8.43002L4.22002 4.21H4.21002ZM21.9 17.4L20.6 18.2H14.3L13 17.4L12.4 18.2L12.42 18.23L17.45 26.8L22.48 18.23L22.5 18.2L21.9 17.4ZM4.79002 5.19L10.8 15.7L14.7 17.14H14.74H15.2H16.85V14.24L12.24 3.09L11.15 5.68L4.79002 5.2V5.19Z"
                    fill="var(--p-primary-200)"
                />
            </svg>
            <div class="inline-flex flex-col gap-2">
                <label for="username" class="text-primary-50 font-semibold">Username</label>
                <InputText id="username" class="!bg-white/20 !border-0 !p-4 !text-primary-50 w-80"></InputText>
            </div>
            <div class="inline-flex flex-col gap-2">
                <label for="password" class="text-primary-50 font-semibold">Password</label>
                <InputText id="password" class="!bg-white/20 !border-0 !p-4 !text-primary-50 w-80" type="password"></InputText>
            </div>
            <div class="flex items-center gap-4">
                <Button label="Cancel" @click="closeCallback" text class="!p-4 w-full !text-primary-50 !border !border-white/30 hover:!bg-white/10"></Button>
                <Button label="Sign-In" @click="closeCallback" text class="!p-4 w-full !text-primary-50 !border !border-white/30 hover:!bg-white/10"></Button>
            </div>
        </div>
    </template>
</Dialog>

该插件还添加了扩展动画工具,可与 styleclassanimateonscroll 指令一起使用。


<Select v-model="animation" :options="animations" placeholder="Select One" class="w-full sm:w-44" />
<div class="py-8 overflow-hidden">
    <div :class="`rounded-border bg-primary w-16 h-16 mx-auto animate-${animation} animate-once animate-duration-1000`"></div>
</div>

动画

属性
animate-fadein淡入 0.15s 线性
animate-fadeout淡出 0.15s 线性
animate-slidedown向下滑动 0.45s 缓入缓出
animate-slideup向上滑动 0.45s 立方贝塞尔曲线 (0, 1, 0, 1)
animate-scalein放大 0.15s 线性
animate-fadeinleft从左淡入 0.15s 线性
animate-fadeoutleft从左淡出 0.15s 线性
animate-fadeinright从右淡入 0.15s 线性
animate-fadeoutright从右淡出 0.15s 线性
animate-fadeinup从上淡入 0.15s 线性
animate-fadeoutup从上淡出 0.15s 线性
animate-fadeindown从下淡入 0.15s 线性
animate-fadeoutup从上淡出 0.15s 线性
animate-width宽度 0.15s 线性
animate-flip翻转 0.15s 线性
animate-flipup向上翻转 0.15s 线性
animate-flipleft淡入 0.15s 线性
animate-flipright向右翻转 0.15s 线性
animate-zoomin放大 0.15s 线性
animate-zoomindown从下放大 0.15s 线性
animate-zoominleft从左放大 0.15s 线性
animate-zoominright从右放大 0.15s 线性
animate-zoominup从上放大 0.15s 线性

动画持续时间

属性
animate-duration-0animation-duration: 0s
animate-duration-75animation-duration: 75ms
animate-duration-100animation-duration: 100ms
animate-duration-200animation-duration: 200ms
animate-duration-300animation-duration: 300ms
animate-duration-400animation-duration: 400ms
animate-duration-500animation-duration: 500ms
animate-duration-700animation-duration: 700ms
animate-duration-1000animation-duration: 1000ms
animate-duration-2000animation-duration: 2000ms
animate-duration-3000animation-duration: 300ms

动画延迟

属性
animate-delay-noneanimation-duration: 0s
animate-delay-75animation-delay: 75ms
animate-delay-100animation-delay: 100ms
animate-delay-150animation-delay: 150ms
animate-delay-200animation-delay: 200ms
animate-delay-300animation-delay: 300ms
animate-delay-400animation-delay: 400ms
animate-delay-500animation-delay: 500ms
animate-delay-700animation-delay: 700ms
animate-delay-1000animation-delay: 1000ms

迭代次数

属性
animate-infiniteanimation-iteration-count: infinite
animate-onceanimation-iteration-count: 1
animate-twiceanimation-iteration-count: 2

方向

属性
animate-normalanimation-direction: normal
animate-reverseanimation-direction: reverse
animate-alternateanimation-direction: alternate
animate-alternate-reverseanimation-direction: alternate-reverse

时间函数

属性
animate-ease-linearanimation-timing-function: linear
animate-ease-inanimation-timing-function: cubic-bezier(0.4, 0, 1, 1)
animate-ease-outanimation-timing-function: cubic-bezier(0, 0, 0.2, 1)
animate-ease-in-outanimation-timing-function: cubic-bezier(0.4, 0, 0.2, 1)

填充模式

属性
animate-fill-noneanimation-fill-mode: normal
animate-fill-forwardsanimation-fill-mode: forwards
animate-fill-backwardsanimation-fill-mode: backwards
animate-fill-bothanimation-fill-mode: both

播放状态

属性
animate-runninganimation-play-state: running
animate-pausedanimation-play-state: paused

背面可见性状态

属性
backface-visiblebackface-visibility: visible
backface-hiddenbackface-visibility: hidden