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 less-loader@5.0.0 --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,不然可能没效果

相关推荐
qq_364371722 小时前
Vue 内置组件 keep-alive 中 LRU 缓存淘汰策略和实现
前端·vue.js·缓存
y先森3 小时前
CSS3中的弹性布局之侧轴的对齐方式
前端·css·css3
你挚爱的强哥7 小时前
✅✅✅【Vue.js】sd.js基于jQuery Ajax最新原生完整版for凯哥API版本
javascript·vue.js·jquery
y先森8 小时前
CSS3中的伸缩盒模型(弹性盒子、弹性布局)之伸缩容器、伸缩项目、主轴方向、主轴换行方式、复合属性flex-flow
前端·css·css3
前端Hardy8 小时前
纯HTML&CSS实现3D旋转地球
前端·javascript·css·3d·html
susu10830189118 小时前
vue3中父div设置display flex,2个子div重叠
前端·javascript·vue.js
IT女孩儿9 小时前
CSS查缺补漏(补充上一条)
前端·css
天天进步201510 小时前
Vue+Springboot用Websocket实现协同编辑
vue.js·spring boot·websocket
疯狂的沙粒10 小时前
如何在Vue项目中应用TypeScript?应该注意那些点?
前端·vue.js·typescript
小镇程序员11 小时前
vue2 src_Todolist全局总线事件版本
前端·javascript·vue.js