vue + less 实现动态主题换肤功能

文章目录


前言

在vue项目中(我的是2.6.11版本的)使用less做到切换主题肤色。话不多说,直接开始。

一、前提条件

1. 初始化vue项目

我这里的项目是2.6.11版本的

bash 复制代码
"vue": "^2.6.11",

2. 安装插件

安装一些less的插件

bash 复制代码
npm install less --save // less插件
npm install [email protected] --save // less-loader作用就是将less代码转译为浏览器可以识别的CSS代码。
npm install style-resources-loader -D // 在样式引入时,对于变量的引入,需要在每个文件里都要引入一遍,为了避免每次使用时都需要单独引入一遍的问题,采用了 style-resources-loader

二、新建文件夹主题theme

路径: src > assets > style > theme

翻译:theme 的中文就是主题

注意点:考虑到切换样式也是样式中的,所以放在style里面,当然,你可以放在任意位置,只要你后面的路径同一改了就好。

1.style.less文件

javascript 复制代码
// 默认的主题颜色(白低黑字)
@baseColor: var(--baseColor, rgba(25,121,255));
@pageBgColor: var(--pageBgColor, rgba(255,255,255));
@scrollBgColor: var(--scrollBgColor, rgba(0, 0, 0));
@resultBgColor: var(--resultBgColor, rgba(255,192,203));
@resultBorderColor: var(--resultBorderColor, rgba(255,255,0));
@resultTextColor: var(--resultTextColor, rgba(0,0,0, 0.9));

// 导出变量 (如果在 src/assets/style/theme/model文件中配置了,就直接导出里面的字体使用)
:export {
  name: "less";
  baseColor: @baseColor;
  pageBgColor: @pageBgColor;
  scrollBgColor: @scrollBgColor;
  resultBgColor: @resultBgColor;
  resultBorderColor: @resultBorderColor;
  resultTextColor: @resultTextColor;
}

2.model.js文件

javascript 复制代码
// 一套默认主题以及一套暗黑主题
export const themes = {
  default: {
    baseColor: `${25}, ${121},${255}`, // 基色(无变化) 
    pageBgColor: `${255}, ${255},${255}`, // 页面的背景色
    scrollBgColor: `${0}, ${0},${0}`, // 滚动条的背景色
    resultBgColor: `${255}, ${192},${203}`, // 结果背景色
    resultBorderColor: `${255}, ${255},${0}`, // 结果区背景色
    resultTextColor: `${0}, ${0},${0}, 0.9`, // 结果文字
  },
  dark: {
    baseColor: `${25}, ${121},${255}`, // 基色(无变化) 
    pageBgColor: `${0}, ${0},${0}`, // 页面的背景色
    scrollBgColor: `${255}, ${255},${255}`, // 滚动条的背景色
    resultBgColor: `${135}, ${206},${235}`, // 结果背景色
    resultBorderColor: `${0}, ${128},${0}`, // 结果区背景色
    resultTextColor: `${255}, ${255},${255}, 0.9`, // 结果文字
  },
};

3.theme.js文件

javascript 复制代码
import { themes } from "./model";
// 修改页面中的样式变量值
const changeStyle = (obj) => {
  for (let key in obj) {
    document
      .getElementsByTagName("body")[0]
      .style.setProperty(`--${key}`, obj[key]);
  }
};
// 改变主题的方法
export const setTheme = (themeName) => {
  localStorage.setItem("theme", themeName); // 保存主题到本地,下次进入使用该主题
  const themeConfig = themes[themeName] ? themes[themeName] : themes['default'];
  changeStyle(themeConfig);
};

theme文件夹最终效果

三、修改vue.config.js文件

javascript 复制代码
const path = require('path');
module.exports = {
  pluginOptions: {
    "style-resources-loader": {
      preProcessor: "less",
      patterns: [
        // 这个是加上自己的路径,不能使用(如下:alias)中配置的别名路径
        path.resolve(__dirname, "./src/assets/style/theme/style.less"),
      ],
    },
  },
};

注意: 修改vue.config.js文件 记得重新启动项目。

四、页面上的具体使用

1. index.vue 页面

javascript 复制代码
<template>
  <div class="index">
    <button class="btn" @click="themeDefault">默认</button>
    <button class="btn" @click="themeDark">暗黑</button>
    <div class="content">
      这是一个可以切换主题的盒子
    </div>  
  </div>  
</template>

<script>
import { setTheme } from "../assets/style/theme/theme"; // 引入切换主题方法
export default {
  data() {
    return {
    }
  },
  methods: {
  // 默认主题方案(白底黑字)
    themeDefault() {
      document.documentElement.removeAttribute('theme-mode'); // 重置为浅色模式
      this.themeChange = true;
      setTheme("default"); // 初始化未默认主题
    },

    // 暗黑主题(黑底白字)
    themeDark() {
      document.documentElement.setAttribute('theme-mode', 'dark'); // 重置为深色模式
      this.themeChange = false;
      setTheme("dark");
    },
  },
  mounted: function() {
    this.themeDefault(); // 进入页面默认渲染默认主题方案
  }
}
</script>

<style lang="less" scoped>
@import '../assets/style/theme/style.less'; // 引入主题样式文件

.index{
  width: 100%;
  height: 100%;
  .btn {
    width: 50px;
    height: 30px;
    background-color: green;
  }
  .content {
    width: 100px;
    height: 100px;
    color: rgba(@resultTextColor, 1);
    background-color: rgba(@resultBgColor, 1);
    border: 10px solid  rgba(@resultBorderColor, 1);
  }
}
</style>

2. index.vue 页面注意点说明

3. index.vue 效果

(1)默认效果

(2)暗黑效果

其他校验修改主题成功的方法

在审查元素的body上有你所定义的数据就是了

五、在js中使用定义的颜色变量

1. 代码

javascript 复制代码
import themsColor from '../assets/style/theme/style.less'; // 引入主题样式文件
export default {
  data() {
    return {
      themsColor,
    }
  },
  mounted: function() {
    console.log('themsColor', themsColor);
  }
}

2. 代码说明

3. 打印themsColor

六、关于定义颜色的变量不是十六进制的原因

如果你在modes.js中使用 #ffffff #333333 类似这样的颜色,其实也是可以的,而且在页面中可以直接使用 color: @resultTextColor,看过去似乎简单了很多,那为什么要改用rgb的方式呢?

相信有仔细注意代码的人可能注意到了这个颜色的值${255}, ${255},${255}, 0.9, 是的,透明度。
如果直接写死的十六进制的话,没有可以操作的空间。包括我实际项目最开始用的也是十六进制,后面才改成的rgb的方式。不仅仅是文字,包括颜色中也会有禁用等需要直接修改透明度的方法,不用因此再添加一个类似的变量考虑才使用的rgba的方法。当然,这也仅仅是一种思路。如果你有更好的方法可以忽略。
注意点:有透明度的就和颜色一样,加在后面就好了,没有透明度的话,就在后面加上1,不然可能没效果

相关推荐
TE-茶叶蛋40 分钟前
Vue Fragment vs React Fragment
javascript·vue.js·react.js
Angindem41 分钟前
从零搭建uniapp项目
前端·vue.js·uni-app
前端小白从0开始3 小时前
Vue3项目实现WPS文件预览和内容回填功能
前端·javascript·vue.js·html5·wps·文档回填·文档在线预览
難釋懷4 小时前
Vue解决开发环境 Ajax 跨域问题
前端·vue.js·ajax
挑战者6668884 小时前
vue入门环境搭建及demo运行
前端·javascript·vue.js
超级土豆粉5 小时前
CSS 预处理器与工具
前端·css
程序猿ZhangSir6 小时前
Vue3 项目的基本架构解读
前端·javascript·vue.js
亲亲小宝宝鸭7 小时前
写了两个小需求,终于搞清楚了表格合并
前端·vue.js
Face7 小时前
路由Vue-router 及 异步组件
前端·javascript·vue.js
风之舞_yjf8 小时前
Vue基础(14)_列表过滤、列表排序
前端·javascript·vue.js