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 插件和无样式模式的 Tailwind 版本。

Tailwind CSS 和 PrimeVue 可以通过两种主要方法一起使用。简单的方法是在 PrimeVue 组件周围使用 Tailwind CSS 进行布局,如下面的示例部分所示,高级方法通过允许 Tailwind CSS 组件内部来样式化整个 UI 套件,从而使集成更进一步无样式模式

PrimeTek 在 无样式模式下,基于 @apply 指令和 IntelliSense 支持,提供了整个 PrimeVue UI 套件的 Tailwind CSS 版本。请访问 PrimeVue 的 Tailwind 版本,获取文档、演示和其他资源。

tailwindcss-primeui 是 PrimeTek 的官方插件,用于提供像 PrimeVue 和 Tailwind CSS 这样的 Prime UI 库之间的首要集成。它被设计为在样式和无样式模式下都能工作。例如,在样式模式下,诸如主要和表面之类的语义颜色作为 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]表面颜色调色板。
主要默认主要颜色。
主要对比默认主要对比色。
主要强调默认主要强调色。
边框表面默认主要强调色。
背景强调强调背景,例如悬停的元素。
背景高亮高亮背景。
背景高亮强调带有强调的高亮背景。
圆角边框边框半径。
文本颜色带有强调的文本颜色。
文本颜色强调默认主要强调色。
文本静音颜色辅助文本颜色。
文本静音颜色强调带有强调的辅助文本颜色。

在样式模式下,由于 css 特异性,Tailwind 实用程序可能无法覆盖默认样式,有两种可能的解决方案。

重要

使用 ! 作为前缀来强制样式。


<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 调色板作为实用程序类。

  • 主要
    50
    100
    200
    300
    400
    500
    600
    700
    800
    900
    950
  • 表面
    0
    50
    100
    200
    300
    400
    500
    600
    700
    800
    900
    950
主要
高亮
盒子

<div class="flex flex-col gap-12">
    <div class="flex gap-6 flex-wrap">
        <div class="rounded-border p-4 border border-transparent flex items-center justify-center bg-primary hover:bg-primary-emphasis text-primary-contrast font-medium flex-auto transition-colors">primary</div>
        <div class="rounded-border p-4 border border-transparent flex items-center justify-center bg-highlight hover:bg-highlight-emphasis font-medium flex-auto transition-colors">highlight</div>
        <div class="rounded-border p-4 border border-surface flex items-center justify-center text-muted-color hover:text-color hover:bg-emphasis font-medium flex-auto transition-colors">box</div>
    </div>
</div>

使用 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>

该插件还添加了扩展的动画实用程序,可以与 样式类滚动时动画 指令一起使用。


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

动画

属性
动画-淡入淡入 0.15 秒线性
动画-淡出淡出 0.15 秒线性
动画-向下滑动向下滑动 0.45 秒缓入缓出
动画-向上滑动向上滑动 0.45 秒三次贝塞尔曲线(0, 1, 0, 1)
动画-放大放大 0.15 秒线性
动画-从左淡入从左淡入 0.15 秒线性
动画-从左淡出从左淡出 0.15 秒线性
动画-从右淡入从右淡入 0.15 秒线性
动画-从右淡出从右淡出 0.15 秒线性
动画-从上淡入从上淡入 0.15 秒线性
动画-从上淡出从上淡出 0.15 秒线性
动画-从下淡入从下淡入 0.15 秒线性
动画-从上淡出从上淡出 0.15 秒线性
动画-宽度宽度 0.15 秒线性
动画-翻转翻转 0.15 秒线性
动画-向上翻转向上翻转 0.15 秒线性
动画-向左翻转淡入 0.15 秒线性
动画-向右翻转向右翻转 0.15 秒线性
动画-放大放大 0.15 秒线性
动画-向下放大向下放大 0.15 秒线性
动画-从左放大从左放大 0.15 秒线性
动画-从右放大从右放大 0.15 秒线性
动画-从上放大从上放大 0.15 秒线性

动画持续时间

属性
动画-持续时间-0动画-持续时间:0 秒
动画-持续时间-75动画-持续时间:75 毫秒
动画-持续时间-100动画-持续时间:100 毫秒
动画-持续时间-200动画-持续时间:200 毫秒
动画-持续时间-300动画-持续时间:300 毫秒
动画-持续时间-400动画-持续时间:400 毫秒
动画-持续时间-500动画-持续时间:500 毫秒
动画-持续时间-700动画-持续时间:700 毫秒
动画-持续时间-1000动画-持续时间:1000 毫秒
动画-持续时间-2000动画-持续时间:2000 毫秒
动画-持续时间-3000动画-持续时间:300 毫秒

动画延迟

属性
动画-延迟-无动画-持续时间:0 秒
动画-延迟-75动画-延迟:75 毫秒
动画-延迟-100动画-延迟:100 毫秒
动画-延迟-150动画-延迟:150 毫秒
动画-延迟-200动画-延迟:200 毫秒
动画-延迟-300动画-延迟:300 毫秒
动画-延迟-400动画-延迟:400 毫秒
动画-延迟-500动画-延迟:500 毫秒
动画-延迟-700动画-延迟:700 毫秒
动画-延迟-1000动画-延迟:1000 毫秒

迭代次数

属性
无限次动画animation-iteration-count: infinite
动画一次animation-iteration-count: 1
动画两次animation-iteration-count: 2

方向

属性
正常方向动画animation-direction: normal
反向动画animation-direction: reverse
交替动画animation-direction: alternate
反向交替动画animation-direction: alternate-reverse

时间函数

属性
线性缓动动画animation-timing-function: linear
缓入动画animation-timing-function: cubic-bezier(0.4, 0, 1, 1)
缓出动画animation-timing-function: cubic-bezier(0, 0, 0.2, 1)
缓入缓出动画animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1)

填充模式

属性
不填充动画animation-fill-mode: normal
向前填充动画animation-fill-mode: forwards
向后填充动画animation-fill-mode: backwards
双向填充动画animation-fill-mode: both

播放状态

属性
运行动画animation-play-state: running
暂停动画animation-play-state: paused

背面可见性状态

属性
背面可见backface-visibility: visible
背面隐藏backface-visibility: hidden