Skip to content

Vue 使用 Less 切换主题

本章是基于 Less 实现全局主题切换功能。

TIP

SCSS 篇请移步 vue 使用 scss 切换主题

前置准备

首先需要确保项目中已经安装了 lessless-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>

核心原理

  1. CSS 变量: 使用 CSS 自定义属性 (--primaryColor) 作为主题色的载体
  2. Less 变量映射: 通过 var(--primaryColor, #809B54) 将 CSS 变量映射到 Less 变量
  3. 动态修改: 通过 JavaScript 动态修改 body 元素的 CSS 变量值
  4. 本地存储: 使用 localStorage 持久化主题配置

Less vs SCSS 对比

特性Less 方案SCSS 方案
实现方式CSS 变量 + JSMixin + 编译时
性能运行时切换编译时确定
灵活性支持动态自定义预定义主题
兼容性需要 CSS 变量支持更好

优势特点

IMPORTANT

  • ✅ 支持运行时动态切换主题
  • ✅ 支持用户自定义主题色
  • ✅ 主题配置持久化到本地
  • ✅ 全局变量自动注入,无需重复引入

总结

使用 Less + CSS 变量的方案可以实现灵活的主题切换功能。相比 SCSS 方案,这种方式支持运行时动态修改,更适合需要用户自定义主题的场景。


如果有问题,欢迎评论区或者私信我 💬

如有转载或 CV 的请标注本站原文地址