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 类)被关闭,这样您就可以通过传递属性完全控制组件样式。当您想基于自定义设计构建自己的 UI 库(通过包装 PrimeVue 组件)或仅仅利用 Tailwind CSS 来为 PrimeVue 组件设置样式时,此功能非常有用。

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

tailwindcss-primeui 是 PrimeTek 提供的官方插件,用于在 Prime UI 库(如 PrimeVue)和 Tailwind CSS 之间提供一流的集成。它旨在同时在样式模式和无样式模式下工作。例如,在样式模式下,语义颜色(如主要颜色和表面颜色)将作为 Tailwind 实用程序提供,例如 bg-primarytext-surface-500text-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-fadeinfadein 0.15s linear
animate-fadeoutfadeout 0.15s linear
animate-slidedownslidedown 0.45s ease-in-out
animate-slideupslideup 0.45s cubic-bezier(0, 1, 0, 1)
animate-scaleinscalein 0.15s linear
animate-fadeinleftfadeinleft 0.15s linear
animate-fadeoutleftfadeoutleft 0.15s linear
animate-fadeinrightfadeinright 0.15s linear
animate-fadeoutrightfadeoutright 0.15s linear
animate-fadeinupfadeinup 0.15s linear
animate-fadeoutupfadeoutup 0.15s linear
animate-fadeindownfadeindown 0.15s linear
animate-fadeoutupfadeoutup 0.15s linear
animate-widthwidth 0.15s linear
animate-flipflip 0.15s linear
animate-flipupflipup 0.15s linear
animate-flipleftfadein 0.15s linear
animate-fliprightflipright 0.15s linear
animate-zoominzoomin 0.15s linear
animate-zoomindownzoomindown 0.15s linear
animate-zoominleftzoominleft 0.15s linear
animate-zoominrightzoominright 0.15s linear
animate-zoominupzoominup 0.15s linear

动画时长

属性
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