可爱静

记录生活、学习和工作

0%

【VUE3】0.2整合Tailwind组件

Tailwind CSS

Tailwind CSS 是一个高度可定制的、实用工具优先的 CSS 框架,它使你能够通过组合小型、单一用途的类来构建现代网站界面,而无需写任何 CSS。

安装

1
npm install -D tailwindcss postcss autoprefixer

此命令会在你的项目中安装三个依赖,它们分别是:

  1. tailwindcss:Tailwind CSS 框架本身。

  2. postcss:一个用于转换 CSS 的工具。

  3. autoprefixer:一个 PostCSS 插件,用于自动添加浏览器供应商前缀到 CSS 规则中,确保跨浏览器的兼容性。

然后,再执行下面的命令,用于生成 tailwind.config.js 和 postcss.config.js 配置文件。

1
npx tailwindcss init -p

配置模板路径

在 tailwind.config.js 文件中添加所有模板文件的路径:

1
2
3
4
5
6
7
8
9
10
11
/** @type {import('tailwindcss').Config} */
export default {
content: [
"./index.html",
"./src/**/*.{vue,js,ts,jsx,tsx}"
],
theme: {
extend: {},
},
plugins: [],
}

将 Tailwind 指令添加到 CSS 文件中

修改 main.js 文件,引入 main.css :

1
2
3
4
5
6
7
8
9
10
11
12
import '@/assets/main.css' # 引入

import { createApp } from 'vue'
import App from '@/App.vue'
// 导入路由
import router from '@/router'

const app = createApp(App)

// 应用路由
app.use(router)
app.mount('#app')

编辑 main.css 文件,清空里面初始化项目时自动生成的 css 代码,添加如下代码:

1
2
3
@tailwind base;
@tailwind components;
@tailwind utilities;

重新构建

1
npm run dev

在项目中使用

编辑 /frontend/index.vue 文件,内容如下:

1
2
3
4
5
<template>
<div class="bg-green-300 inline">绿色</div>
<div class="bg-yellow-300 ml-2 inline">黄色</div>
<div class="bg-blue-300 ml-2 inline">蓝色</div>
</template>

我们在 div 标签上添加了一些 Tailwind CSS 库中的样式类:

  • bg-green-300 : 绿色背景;
  • bg-yellow-300 : 黄色背景;
  • bg-blue-300 : 蓝色背景;
  • inline : 相当于 display: inline;
  • ml-2 : 相当于 margin-left;

响应式设计

通过在 Tailwind 类名前添加前缀,你可以轻松地应用不同的样式于不同屏幕尺寸:

1
2
3
<div class="text-xs sm:text-lg md:text-xl lg:text-2xl">
响应式字体
</div>

更多样式类,可查询官网:Installation - Tailwind CSS ,应有尽有!

Tailwind CSS 组件库:Flowbite

Flowbite 是一个基于 Tailwind CSS 创建的组件库,旨在帮助开发者快速构建现代、响应式的 Web 应用界面。

安装

1
npm install flowbite

在 tailwind.config.js 文件添加 Flowbit 插件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/** @type {import('tailwindcss').Config} */
export default {
content: [
"./index.html",
"./src/**/*.{vue,js,ts,jsx,tsx}"
],
theme: {
extend: {},
},
plugins: [
// 添加插件
require('flowbite/plugin')
]
}

另外, 还需要在 tailwind.config.js 文件中,添加 js 相关的文件,因为页面交互需要 js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/** @type {import('tailwindcss').Config} */
export default {
content: [
"./index.html",
"./src/**/*.{vue,js,ts,jsx,tsx}",
// 添加此行
"/node_modules/flowbite/**/*.js",
],
theme: {
extend: {},
},
plugins: [
require('flowbite/plugin')
]
}

使用 Flowbite

Flowbit 支持的组件列表,大家可以去官网:Tailwind CSS Accordion - Flowbite 查看。

在 /frontend/index.vue 首页文件中添加 Navbar 导航栏头的源码,并将几处跳转的地方改为中文,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
<template>
<nav class="bg-white border-gray-200 border-b dark:bg-gray-900">
<div class="max-w-screen-xl flex flex-wrap items-center justify-between mx-auto p-4">
<a href="/" class="flex items-center">
<img src="https://flowbite.com/docs/images/logo.svg" class="h-8 mr-3" alt="Flowbite Logo" />
<span class="self-center text-2xl font-semibold whitespace-nowrap dark:text-white">嘿凡的前端项目</span>
</a>
<div class="flex md:order-2">
<button type="button" data-collapse-toggle="navbar-search" aria-controls="navbar-search"
aria-expanded="false"
class="md:hidden text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 focus:outline-none focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 rounded-lg text-sm p-2.5 mr-1">
<svg class="w-5 h-5" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none"
viewBox="0 0 20 20">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="m19 19-4-4m0-7A7 7 0 1 1 1 8a7 7 0 0 1 14 0Z" />
</svg>
<span class="sr-only">Search</span>
</button>
<div class="relative hidden md:block">
<div class="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
<svg class="w-4 h-4 text-gray-500 dark:text-gray-400" aria-hidden="true"
xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 20">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="m19 19-4-4m0-7A7 7 0 1 1 1 8a7 7 0 0 1 14 0Z" />
</svg>
<span class="sr-only">Search icon</span>
</div>
<input type="text" id="search-navbar"
class="block w-full p-2 pl-10 text-sm text-gray-900 border border-gray-300 rounded-lg bg-gray-50 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
placeholder="请输入关键词...">
</div>
<button data-collapse-toggle="navbar-search" type="button"
class="inline-flex items-center p-2 w-10 h-10 justify-center text-sm text-gray-500 rounded-lg md:hidden hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-gray-200 dark:text-gray-400 dark:hover:bg-gray-700 dark:focus:ring-gray-600"
aria-controls="navbar-search" aria-expanded="false">
<span class="sr-only">Open main menu</span>
<svg class="w-5 h-5" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none"
viewBox="0 0 17 14">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M1 1h15M1 7h15M1 13h15" />
</svg>
</button>
</div>
<div class="items-center justify-between hidden w-full md:flex md:w-auto md:order-1" id="navbar-search">
<div class="relative mt-3 md:hidden">
<div class="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
<svg class="w-4 h-4 text-gray-500 dark:text-gray-400" aria-hidden="true"
xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 20">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="m19 19-4-4m0-7A7 7 0 1 1 1 8a7 7 0 0 1 14 0Z" />
</svg>
</div>
<input type="text" id="search-navbar"
class="block w-full p-2 pl-10 text-sm text-gray-900 border border-gray-300 rounded-lg bg-gray-50 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
placeholder="Search...">
</div>
<ul
class="flex flex-col p-4 md:p-0 mt-4 font-medium border border-gray-100 rounded-lg bg-gray-50 md:flex-row md:space-x-8 md:mt-0 md:border-0 md:bg-white dark:bg-gray-800 md:dark:bg-gray-900 dark:border-gray-700">
<li>
<a href="#"
class="block py-2 pl-3 pr-4 text-white bg-blue-700 rounded md:bg-transparent md:text-blue-700 md:p-0 md:dark:text-blue-500"
aria-current="page">首页</a>
</li>
<li>
<a href="#"
class="block py-2 pl-3 pr-4 text-gray-900 rounded hover:bg-gray-100 md:hover:bg-transparent md:hover:text-blue-700 md:p-0 md:dark:hover:text-blue-500 dark:text-white dark:hover:bg-gray-700 dark:hover:text-white md:dark:hover:bg-transparent dark:border-gray-700">分类</a>
</li>
<li>
<a href="#"
class="block py-2 pl-3 pr-4 text-gray-900 rounded hover:bg-gray-100 md:hover:bg-transparent md:hover:text-blue-700 md:p-0 dark:text-white md:dark:hover:text-blue-500 dark:hover:bg-gray-700 dark:hover:text-white md:dark:hover:bg-transparent dark:border-gray-700">标签</a>
</li>
<li>
<a href="#"
class="block py-2 pl-3 pr-4 text-gray-900 rounded hover:bg-gray-100 md:hover:bg-transparent md:hover:text-blue-700 md:p-0 dark:text-white md:dark:hover:text-blue-500 dark:hover:bg-gray-700 dark:hover:text-white md:dark:hover:bg-transparent dark:border-gray-700">归档</a>
</li>
</ul>
</div>
</div>
</nav>
</template>

<script setup>
import { onMounted } from 'vue'
import { initCollapses } from 'flowbite'

// 初始化 flowbit 相关组件
onMounted(() => {
initCollapses();
})
</script>

解释一下 <script> 中的代码:

  • onMounted 是一个生命周期钩子(lifecycle hook)。生命周期钩子是 Vue 组件在其生命周期的不同阶段可以调用的函数。onMounted 钩子在组件被挂载到 DOM 之后立即调用。这意味着,当此钩子被触发时,你可以安全地访问和操作组件的 DOM 元素;

  • initCollapses() 用于初始化 flowbite 的 collapse 组件,有了它,当页面在移动端展示时,点击菜单收缩按钮,可查看隐藏的菜单选项。

然后,在 main.css 中添加 <body> 标签的基本样式:

1
2
3
4
5
6
7
body {
font-family: -apple-system-font,BlinkMacSystemFont,Helvetica Neue,PingFang SC,Hiragino Sans GB,Microsoft YaHei UI,Microsoft YaHei,Arial,sans-serif;
color: #4c4e4d;
font-size: 16px;
background: #f4f4f4;
line-height: 1.6;
}

添加【登录】超链接

1
2
<!-- 登录 -->
<div class="text-gray-900 ml-1 mr-1 hover:text-blue-700">登录</div>

注意,为了让登录超链接垂直居中,还需要在父级 <div> 中添加样式 items-center, 以及边距调整。最终代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
<template>
<nav class="bg-white border-gray-200 border-b dark:bg-gray-900">
<div class="max-w-screen-xl flex flex-wrap items-center justify-between mx-auto p-4">
<a href="/" class="flex items-center">
<img src="https://flowbite.com/docs/images/logo.svg" class="h-8 mr-3" alt="Flowbite Logo" />
<span class="self-center text-2xl font-semibold whitespace-nowrap dark:text-white">嘿凡的前端项目</span>
</a>
<div class="flex items-center md:order-2">
<button type="button" data-collapse-toggle="navbar-search" aria-controls="navbar-search"
aria-expanded="false"
class="md:hidden text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 focus:outline-none focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 rounded-lg text-sm p-2.5 mr-1">
<svg class="w-5 h-5" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none"
viewBox="0 0 20 20">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="m19 19-4-4m0-7A7 7 0 1 1 1 8a7 7 0 0 1 14 0Z" />
</svg>
<span class="sr-only">Search</span>
</button>
<div class="relative hidden mr-2 md:block">
<div class="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
<svg class="w-4 h-4 text-gray-500 dark:text-gray-400" aria-hidden="true"
xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 20">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="m19 19-4-4m0-7A7 7 0 1 1 1 8a7 7 0 0 1 14 0Z" />
</svg>
<span class="sr-only">Search icon</span>
</div>
<input type="text" id="search-navbar"
class="block w-full p-2 pl-10 text-sm text-gray-900 border border-gray-300 rounded-lg bg-gray-50 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
placeholder="请输入关键词...">
</div>
<!-- 登录 -->
<div class="text-gray-900 ml-1 mr-1 hover:text-blue-700">登录</div>
<button data-collapse-toggle="navbar-search" type="button"
class="inline-flex items-center p-2 w-10 h-10 justify-center text-sm text-gray-500 rounded-lg md:hidden hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-gray-200 dark:text-gray-400 dark:hover:bg-gray-700 dark:focus:ring-gray-600"
aria-controls="navbar-search" aria-expanded="false">
<span class="sr-only">Open main menu</span>
<svg class="w-5 h-5" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none"
viewBox="0 0 17 14">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M1 1h15M1 7h15M1 13h15" />
</svg>
</button>
</div>
<div class="items-center justify-between hidden w-full md:flex md:w-auto md:order-1" id="navbar-search">
<div class="relative mt-3 md:hidden">
<div class="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
<svg class="w-4 h-4 text-gray-500 dark:text-gray-400" aria-hidden="true"
xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 20">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="m19 19-4-4m0-7A7 7 0 1 1 1 8a7 7 0 0 1 14 0Z" />
</svg>
</div>
<input type="text" id="search-navbar"
class="block w-full p-2 pl-10 text-sm text-gray-900 border border-gray-300 rounded-lg bg-gray-50 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
placeholder="Search...">
</div>
<ul
class="flex flex-col p-4 md:p-0 mt-4 font-medium border border-gray-100 rounded-lg bg-gray-50 md:flex-row md:space-x-8 md:mt-0 md:border-0 md:bg-white dark:bg-gray-800 md:dark:bg-gray-900 dark:border-gray-700">
<li>
<a href="#"
class="block py-2 pl-3 pr-4 text-white bg-blue-700 rounded md:bg-transparent md:text-blue-700 md:p-0 md:dark:text-blue-500"
aria-current="page">首页</a>
</li>
<li>
<a href="#"
class="block py-2 pl-3 pr-4 text-gray-900 rounded hover:bg-gray-100 md:hover:bg-transparent md:hover:text-blue-700 md:p-0 md:dark:hover:text-blue-500 dark:text-white dark:hover:bg-gray-700 dark:hover:text-white md:dark:hover:bg-transparent dark:border-gray-700">分类</a>
</li>
<li>
<a href="#"
class="block py-2 pl-3 pr-4 text-gray-900 rounded hover:bg-gray-100 md:hover:bg-transparent md:hover:text-blue-700 md:p-0 dark:text-white md:dark:hover:text-blue-500 dark:hover:bg-gray-700 dark:hover:text-white md:dark:hover:bg-transparent dark:border-gray-700">标签</a>
</li>
<li>
<a href="#"
class="block py-2 pl-3 pr-4 text-gray-900 rounded hover:bg-gray-100 md:hover:bg-transparent md:hover:text-blue-700 md:p-0 dark:text-white md:dark:hover:text-blue-500 dark:hover:bg-gray-700 dark:hover:text-white md:dark:hover:bg-transparent dark:border-gray-700">归档</a>
</li>
</ul>
</div>
</div>
</nav>
</template>

<script setup>
import { onMounted } from 'vue'
import { initCollapses } from 'flowbite'

// 初始化 flowbit 相关组件
onMounted(() => {
initCollapses();
})
</script>

总结

对后端来说,这样的组件非常友好,继续学习。