使用vite + Tailwindcss搭建基础框架
git仓库地址快速访问项目
目前比较常见的换肤方式
- 编写多套css文件(一套主题一套样式),通过动态修改link标签的href来实现换肤
- 通过css变量来实现换肤,通过配置css变量,增加class调用不同css变量实现换肤
创建vite项目
// 使用NPM方式
npm init vite@latest
// 默认选择vue + ts版本
初始化Tailwind CSS
- 安装Tailwind依赖
npm install -D tailwindcss@latest postcss@latest autoprefixer@latest
- 生成tailwind.config.js
npx tailwindcss init -p
// 执行命令之后 会生成最小化的tailwind.config.js
// tailwind.config.js
module.exports = {
purge: [], // 在生产环境去除没有用到的css变量
darkMode: false, // or 'media' or 'class' 是否开启暗黑模式 默认不开启
theme: {// 主题配置
extend: {// 主题扩展配置 比如增加color或者自定义color
},
},
variants: {
extend: {},
},
plugins: [],
}
- 创建主样式文件 index.scss,定义主题变量
// index.scss
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
// 默认主题色蓝色
:root {
// 背景色
--color-bg-base: 191, 219, 254;
// 卡片颜色
--color-bg-card: 147, 197, 253;
// 按钮颜色
--color-bg-btn: 96, 165, 250;
// 按钮hover颜色
--color-bg-btn-hover: 59, 130, 246;
// 字体颜色
--color-text-base: #3B82F6;
// 按钮字体颜色
--color-btn-base: #fff;
}
.theme-pink {
// 背景色
--color-bg-base: 251, 207, 232;
// 卡片颜色
--color-bg-card: 249, 168, 212;
// 按钮颜色
--color-bg-btn: 244, 114, 182;
// 按钮hover颜色
--color-bg-btn-hover: 236, 72, 153;
// 字体颜色
--color-text-base: #EC4899;
// 按钮字体颜色
--color-btn-base: #fff;
}
.theme-dark {
// 背景色
--color-bg-base: 17, 24, 39;
// 卡片颜色
--color-bg-card: 55, 65, 81;
// 按钮颜色
--color-bg-btn: 75, 85, 99;
// 按钮hover颜色
--color-bg-btn-hover: 107, 114, 128;
// 字体颜色
--color-text-base: #fff;
// 按钮字体颜色
--color-btn-base: #fff;
}
}
@layer components {
.s-btn { // 按钮的基础样式
@apply bg-skin-btn hover:bg-skin-btn-hover px-4 py-2 rounded;
}
.s-card { // 卡片的基础样式
@apply bg-skin-card rounded-2xl p-8 min-w-max min-h-max flex flex-col items-center;
}
}
- 修改tailwind.config.js中的配置
/** @type {import('tailwindcss').Config} */
// 该方法是为了颜色基础类可以提供设置透明度的快捷方式,
function withOpacityValue(variable) {
// 返回一个函数,透明度为可选参数,这样在 HTML 元素中使用颜色基础类时,既可以采用 text-blue-500 方式,也支持 text-blue-500/20 快捷同时设置透明度的形式
return ({ opacityValue }) => {
if (opacityValue === undefined) {
return `rgb(var(${variable}))`;
}
return `rgba(var(${variable}), ${opacityValue})`;
};
}
module.exports = {
darkMode: 'class', // media跟随系统颜色, class:允许用户主动切换
content: [
'./index.html',
'./src/**/*.{vue,js,ts,tsx,jsx}'
],
theme: {
extend: {
backgroundColor: { // 此处用来定义主题的背景色基础样式
skin: {
bg: withOpacityValue('--color-bg-base'),
card: withOpacityValue('--color-bg-card'),
btn: withOpacityValue('--color-bg-btn'),
'btn-hover': withOpacityValue('--color-bg-btn-hover'),
}
},
textColor: { // 文本的基础样式
'primary': 'var(--color-text-base)',
'btn-base': 'var(--color-btn-base)',
}
},
},
plugins: [],
}
- 在main.ts中引入
import { createApp } from 'vue'
import './index.scss'
import App from './App.vue'
createApp(App).mount('#app')
- 创建Theme.vue组件
<template>
<!--背景颜色-->
<div class="transition-all bg-skin-bg h-screen flex justify-center items-center">
<!--卡片颜色-->
<div class="s-card">
<h1 class="text-3xl font-extrabold text-primary">尝试定制你的主题</h1>
<h2 class="text-lg my-3 text-amber-50">使用Tailwindcss和css变量实现换肤</h2>
<div class="w-full flex justify-evenly space-x-2">
<button class="s-btn text-btn-base" @click="changeTheme()">蓝色主题</button>
<button class="s-btn text-btn-base" @click="changeTheme(THEME_LIST[0])">粉色主题</button>
<button class="s-btn text-btn-base" @click="changeTheme(THEME_LIST[1])">黑色主题</button>
</div>
</div>
</div>
</template>
<script setup lang="ts">
const THEME_LIST = ['theme-pink', 'theme-dark']
const changeTheme = function(theme: string = '') {
const classList = document.documentElement.classList
THEME_LIST.forEach(item => document.documentElement.classList.remove(item))
if (theme) {
classList.add(theme)
}
}
</script>
<style>
</style>
- 在APP.vue中引入Theme组件
<script setup lang="ts">
import Theme from './components/Theme.vue'
</script>
<template>
<Theme />
</template>
- 效果如下
- 默认主题色
- 粉色主题
- 黑色主题