主题
Vue 使用 Less 切换主题
本章是基于 Less 实现全局主题切换功能。
TIP
SCSS 篇请移步 vue 使用 scss 切换主题
前置准备
首先需要确保项目中已经安装了 less、less-loader 以及以下必要插件:
bash
npm install less less-loader -D
npm install style-resources-loader -D
npm install vue-cli-plugin-style-resources-loader -D配置步骤
1. 创建主题配置文件
在 src 文件下新建一个 style 文件夹,里面创建一个 theme.less 文件。
theme.less
此处配置的是主题默认颜色,使用 CSS 变量作为回退值。
less
// 此处配置的是主题默认颜色
@primaryColor: var(--primaryColor, #809b54);
@bgColor: var(--bgColor, #ccc);
// 导出变量
:export {
name: 'less';
primaryColor: @primaryColor;
bgColor: @bgColor;
}2. 配置 vue.config.js
在项目根目录的 vue.config.js 中配置全局 Less 变量:
javascript
const path = require('path')
module.exports = {
pluginOptions: {
'style-resources-loader': {
preProcessor: 'less',
patterns: [
// 此处为上面创建的文件路径
path.resolve(__dirname, './src/style/theme.less'),
],
},
},
}NOTE
配置完成后,项目就可以全局访问到 theme.less 文件里面的变量了。
测试变量访问
尝试在组件中使用变量,确保配置生效:
less
.dialog-code {
background-color: @bgColor;
padding: 20px;
box-sizing: border-box;
border-radius: 5px;
}TIP
如果访问不到变量,可以手动引入: @import url('../style/theme.less');
3. 创建主题管理器
在 style 文件夹下新建 handle.js 文件,用于管理主题切换逻辑。
handle.js
javascript
// 定义主题配置
const themes = {
default: {
// 默认主题
primaryColor: '#809B54',
bgColor: '#ccc',
},
light: {
// 亮色主题
primaryColor: '#9A8A71',
bgColor: '#fff',
},
dark: {
// 暗色主题
primaryColor: '#487650',
bgColor: '#000',
},
}
// 修改页面中的样式变量值
const changeStyle = (obj) => {
for (const key in obj) {
document.getElementsByTagName('body')[0].style.setProperty(`--${key}`, obj[key])
}
}
// 改变主题的方法
export const setTheme = (themeName) => {
localStorage.setItem('theme', themeName) // 保存主题到本地,下次进入使用该主题
const themeConfig = themes[themeName]
// 如果有主题名称,那么则采用我们定义的主题
if (themeConfig) {
localStorage.setItem('primaryColor', themeConfig.primaryColor) // 保存主题色到本地
localStorage.setItem('bgColor', themeConfig.bgColor) // 保存背景色到本地
changeStyle(themeConfig) // 改变样式
} else {
// 从本地存储中恢复自定义主题
const themeConfig = {
primaryColor: localStorage.getItem('primaryColor'),
bgColor: localStorage.getItem('bgColor'),
}
changeStyle(themeConfig)
}
}4. 在 Vue 组件中使用
配置完成后,在需要切换主题的页面引入 handle.js,使用 setTheme 方法来切换主题。
完整示例
vue
<template>
<div class="box">
<button @click="defaul">默认主题</button>
<button @click="light">亮色主题</button>
<button @click="dark">暗色主题</button>
<button @click="custom">自定义主题</button>
</div>
</template>
<script>
import { setTheme } from '../style/handle.js'
export default {
name: 'ThemeDemo',
mounted() {
this.init() // 初始化主题
},
methods: {
// 初始化默认主题
init() {
setTheme('default')
},
// 更改为默认主题
defaul() {
setTheme('default')
},
// 亮色主题
light() {
setTheme('light')
},
// 暗色主题
dark() {
setTheme('dark')
},
// 自定义主题
custom() {
const myColor = 'green'
localStorage.setItem('primaryColor', myColor) // 将新的主题色存入本地
setTheme() // 应用自定义主题
},
},
}
</script>
<style scoped lang="less">
.box {
color: @primaryColor;
background-color: @bgColor;
padding: 20px;
button {
margin: 10px;
padding: 8px 16px;
cursor: pointer;
}
}
</style>核心原理
- CSS 变量: 使用 CSS 自定义属性 (
--primaryColor) 作为主题色的载体 - Less 变量映射: 通过
var(--primaryColor, #809B54)将 CSS 变量映射到 Less 变量 - 动态修改: 通过 JavaScript 动态修改
body元素的 CSS 变量值 - 本地存储: 使用
localStorage持久化主题配置
Less vs SCSS 对比
| 特性 | Less 方案 | SCSS 方案 |
|---|---|---|
| 实现方式 | CSS 变量 + JS | Mixin + 编译时 |
| 性能 | 运行时切换 | 编译时确定 |
| 灵活性 | 支持动态自定义 | 预定义主题 |
| 兼容性 | 需要 CSS 变量支持 | 更好 |
优势特点
IMPORTANT
- ✅ 支持运行时动态切换主题
- ✅ 支持用户自定义主题色
- ✅ 主题配置持久化到本地
- ✅ 全局变量自动注入,无需重复引入
总结
使用 Less + CSS 变量的方案可以实现灵活的主题切换功能。相比 SCSS 方案,这种方式支持运行时动态修改,更适合需要用户自定义主题的场景。
如果有问题,欢迎评论区或者私信我 💬
