Vue + less implements dynamic theme skinning function


foreword

In the vue project (mine is version 2.6.11), use less to switch the theme color. Without further ado, let's start directly.

1. Preconditions

1. Initialize the vue project

My project here is version 2.6.11

"vue": "^2.6.11",

2. Install the plugin

Install some less plugins

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

2. Create a new folder theme theme

Path: src > assets > style > theme
Translation: The Chinese of theme is the theme
Note: Considering that the switching style is also included in the style, it is placed in the style, of course,你可以放在任意位置,只要你后面的路径同一改了就好。

1. style.less file

// 默认的主题颜色(白低黑字)
@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 file

// 一套默认主题以及一套暗黑主题
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 file

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);
};

The final effect of the theme folder

insert image description here

3. Modify the vue.config.js file

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文件 记得重新启动项目。

Fourth, the specific use on the page

1. index.vue page

<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. Notes on the index.vue page

insert image description here

3. index.vue effect

(1) Default effect
insert image description here
(2) Dark effect
insert image description here

Other methods to verify the success of modifying the theme
Just have the data you defined on the body of the review element
insert image description here

5. Use the defined color variable in js

1. Code

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

2. Code Description

insert image description here

3. Print themColor

insert image description here

6. The reason why the variable defining the color is not hexadecimal

If you use a color like #ffffff #333333 in modes.js, it is actually possible, and it can be used directly on the page color: @resultTextColor. It seems to be much simpler in the past, so why use the rgb method instead?
I believe that someone who pays close attention to the code may have noticed the value of this color ${255}, ${255},${255}, 0.9, yes, transparency.
如果直接写死的十六进制的话,没有可以操作的空间. Including my actual project, I used hexadecimal at the beginning, and then changed it to rgb. Not only the text, but also the color will have a method that needs to directly modify the transparency, such as disabling, so there is no need to add a similar variable to consider the rgba method. Of course, this is just a way of thinking. Ignore if you have a better way.
注意点:有透明度的就和颜色一样,加在后面就好了,没有透明度的话,就在后面加上1,不然可能没效果.

Guess you like

Origin blog.csdn.net/weixin_44784401/article/details/132237441