主题切换实现(vue-less)

介绍

  1. 本文适合黑白切换或者主题样式偏少的(建议:2-10种);主题越多,样式会越多。理论上无限套。
  2. 本文适合已经写好了一套主题,然后需求增加第二套或者多套主题(最好小于10套,当然也可以更多,但是样式也会更多)
  3. 本文以 vue + vue-cli2.x + element-ui +vuex举例

实现

  1. 您需要实现全局样式文件
    1)在/src/main.js引入全局样式文件;如果有使用插件实现全局样式引入的则,只需要确保你的全局样式文件可以覆盖掉 UI 组件的样式

    import Vue from 'vue'
    import App from './App'
    import ElementUI from 'element-ui'
    import 'element-ui/lib/theme-chalk/index.css';
    
    import "./styles/index.less";
    
    new Vue({
      render: h => h(App),
      data: {
    	eventHub: new Vue()
      }
    }).$mount('#app');
    
    
    

    2)个人建议在 src文件夹下创建一个 styles文件夹来管理全局样式。因为这块可以使用less的mixin来抽离成样式组件。
    3)styles最终如下图集成模式为下图
    在这里插入图片描述

  2. 在 styles 文件夹中增加 index.less、theme.less、allVar.js、allVar.less 四个文件;theme、components两个文件夹。(如上图)
    1)index.less主入口

    @import './theme.less';
    

    2)theme.less负责引入主题中的index.less文件

    @import './theme/White/index.less'; // 白色主题
    @import './theme/Black/index.less'; // 黑色主题
    

    3)allVar.js你的所有主题都需要在这里引入,主要是负责js中使用less变量(颜色、字体大小等)而存在的

    import black from '@/styles/anHui-new/theme/Black/var.less';
    import white from '@/styles/anHui-new/theme/White/var.less';
    // 获取 less 变量颜色
    export default {
    	black,
    	white
    }
    

    4)allVar.less集合所有主题中的变量文件,如果后续需要在页面内使用主题变量的话(非常不建议在页面内使用!因为会使后续增加主题提高难度!)

    @import './theme/Black/var.less';
    @import './theme/White/var.less';
    
  3. 以黑白两种主题来介绍;
    1)src/styles/theme中增加 Black 和 White 两个文件夹;并且同时增加 index.less 和 var.less文件;建议在文件夹中再次增加components文件夹;如下图
    在这里插入图片描述
    2)此时theme中每一个文件夹则是一种主题色的配置;我们以黑色 Black (style/theme/Black) 来举例子:
    (1)Black/index.less

    @import './var.less'; // 引入当前主题的变量
    @import '../../components/FontColor/index.less'; // 全局引入修改字体颜色的less方法(mixin)
    @import '../../components/Select/index.less'; // 引入下拉框的less方法(mixin实现)
    .theme-black-731514100-random {
    	.el-select-dropdown(@select-bg-color: @black-select-bg-color, @select-border-color: @black-select-border-color);
    }
    

    (2)Black/var.less命名规范建议以主题色为开头(比如@black-xxxxx;@white-xxxxx)

    // 基础色
    @black-base-color: #0080FF;
    @black-base-bg-pop-color: rgba(0, 13, 26, .8);
    
    // 下拉框
    @black-select-border-color: #00D5FF;
    @black-select-bg-color: @black-base-bg-pop-color;
    
    :export {
      base-color: @black-base-color;
      base-bg-pop-color: @black-base-bg-pop-color;
    }
    

    温馨提示1:上文中的 :export 为less文件的导出变量;可以直接在 js 中使用颜色;(直接import xxx from 'styles/theme/Black/var.less’即可看到已经编译好的对象)
    温馨提示2:目前没有发现可以直接导出当前less文件全部变量。只能自己手动导出变量;
    温馨提示3:导出变量一定要与上面一样;因为在vuex可以直接切换主题名字进行切换主题,到时候选取的变量名要保持一致!

    3)此时你会发现我引入了 components 中的两个 less 组件内容;那么我们开始介绍这两个组件;
    (1)切换到 components 目录(src/styles/components);增加两个文件夹:Select、FontColor;文件夹中都含有个index.less;如下图:
    在这里插入图片描述
    (2)FontColor和Select都是使用less的mixin抽成为方法了;如果不了解的话可以去 less 官网看看 mixin 如何使用
    (3)FontColor/index.less;修改字体颜色的

    .changeFontColor(@color) {
    	color: @color;
    	a,
    	span,
    	div,
    	label,
    	i {
    		color: @color;
    	}
    }
    .changeFontColorImportant(@color) {
    	color: @color !important;
      	a,
    	span,
    	div,
    	label,
    	i {
    		color: @color !important;
      	}
    }
    

    (4)Select/index.less;全局修改下拉框样式组件

    .el-select-activeClass(@select-border-color) {
    	background: transparent !important;
    	.changeFontColor(@select-border-color); // 这个是因为外部引入了 FontColor 组件的原因;
    }
    
    .el-select-dropdown(@select-bg-color, @select-border-color) {
    	background: @select-bg-color;
    	border: 1px solid @select-border-color;
    
    	.popper__arrow::after {
    		border-bottom-color: @select-border-color;
    	}
    
    	.selected {
    		.el-select-activeClass(@select-border-color)
    	}
    
    	.hover {
    		.el-select-activeClass(@select-border-color)
    	}
    }
    
  4. 挂载
    (1)增加文件:src/mixin/theme.js

    import { mapGetters, mapMutations } from 'vuex';
    
    export default {
      	computed: {
      	 	...mapGetters('style', ['theme'])
      	},
     	watch: {
    	 	theme() {
    	   		this.setTheme();
    	   	}
     	},
    	mounted() {
    	  	this.setTheme()
    	},
    	methods: {
    		 ...mapMutations('style', ['changeTheme']),
     		 setTheme() {
     	 		 document.getElementsByTagName('body')[0].className = `theme-${this.theme}-731514100-random`
    	 	 },
      	}
    }
    

    (2)在你页面的主入口混入(mixins)src/mixin/theme.js这个文件;比如说(app.vue中)

    <template>
    	<div id="app" style="height:100%">
    		<router-view></router-view>
    	</div>
    </template>
    
    <script>
    import themeMixin from "@/mixin/theme.js";
    export default {
    	name: 'App',
    	mixins: [
    		/** themeMixin: 主题挂载
     	 	 * @computed theme
     	 	 * @method setTheme
     	 	 * @watch theme
     	 	 */
    		themeMixin
    	],
    }
    </script>
    
  5. vuex状态管理数据,实现切换主题功能,实现获取less变量值功能;
    (1)使用vuex状态管理;创建文件:src/store/modules/style.js;此处使用到了命名空间,如果对命名空间不理解的话可以去vuex官网看看。(namespaced: true为开启命名空间

    import style from '@/styles/anHui-new/allVar.js';
    export default {
      namespaced: true,
      state: {
        themeList: [
          {
            type: 'white',
            style: style.white
          },
          {
            type: 'black',
            style: style.black
          }
        ],
        theme: 'black'
      },
      mutations: {
        changeTheme(state, data) { // 改变主题调用此函数;唯一参数:传递改变为哪个主题、或者在第一个和第二个主题切换。
          state.theme = data || state.themeList.reduce((pre, next, i, arr) => {
            if (pre) return pre;
            if (next.type !== state.theme) pre = next.type;
            return pre
          }, void 0)
        }
      },
      getters: {
        theme: (state) => state.theme, // 获取当前主题是哪个
        globalColor: (state) => (style[state.theme]) // 会返回你定义的对象-返回当前主题的变量颜色
      }
    }
    
    

    温馨提示:上面这个文件需要挂载到vuex里面去;如果已经挂载过了则不需要走以下不走了;实现如下:
    (2)挂载到vuex中(src/store/index.js)

    import Vue from 'vue';
    import Vuex from 'vuex';
    Vue.use(Vuex)
    let moduleInclude = {
      state: {
      },
      actions: {
      },
      mutations: {
      }
    }
    
    const modulesFiles = require.context('./modules', true, /\.js$/)
    const modules = modulesFiles.keys().reduce((modules, modulePath) => {
      const name = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1'),
        value = modulesFiles(modulePath);
      modules[name] = value.default;
      return modules;
    }, {})
    
    export default new Vuex.Store({
      modules: {
        moduleInclude,
        ...modules
      }
    })
    

    (3)在 src/main.js 中挂到 vue 中

    import Vue from 'vue'
    import App from './App'
    import ElementUI from 'element-ui'
    import 'element-ui/lib/theme-chalk/index.css';
    import store from './store'; // 这个是挂载vuex的
    import "./styles/index.less";
    
    new Vue({
      store,
      render: h => h(App),
      data: {
    	eventHub: new Vue()
      }
    }).$mount('#app');
    
  6. 引用示例

    <template>
     	<div>
    		<button @click="changeTheme()">changeTheme</button>
    		 <!-- 这里写你的下拉框组件去测试吧 -->
    	</div>
    </template>
    
    <script>
    import { mapGetters, mapMutations } from "vuex";
    import themeMixin from "@/mixin/theme.js";
    export default {
      data() {
        return {
        };
      },
      mixins: [
        /** themeMixin: 主题挂载
         * @computed theme
         * @method setTheme
         * @watch theme
         */
        themeMixin,
      ],
      computed: {
        ...mapGetters("style", ["theme"]),
      },
      methods: {
        ...mapMutations("style", ["changeTheme"])
      },
    };
    </script>
    
    
  7. 此时如果你完成了以上步骤,则可以看到你的下拉框可以被覆盖颜色了
    在这里插入图片描述
    在这里插入图片描述

总结

  1. 功能持续加强版:可集成一个项目模块,专门来配置项目主题色。最后生成样式配置文件。(src/styles/theme/xxxxxx: index.less 和 var.less);
  2. 切换主题这功能好像可以使用css-vars-ponyfill这个插件更好的去实现样;有兴趣的小伙伴可以去研究一下(期待你的回信);css-vars-ponyfill官网地址
  3. 如果你有更好的实现方案,可以一起讨论~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/12701.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

8、ThingsBoard使用docker compose集群部署的问题以及如何解决问题

1、问题回顾 接着上一节继续讲解,上一节我们把整个服务全部都运行起来了,但是访问页面报错,最后查看的问题是前端的容易里面报错: 然后执行脚本删除所有的容器 2、问题分析 当遇到这个问题的时候,我当时真的不知道如何去解决,然后我又尝试使用官方的镜像来部署,发现官…

ASM字节码处理工具原理及实践(一)

1. ASM简介 我们知道程序的分析。生成和转换是很有用的技术&#xff0c;可以用于很多场景。ASM作为一个Java字节码处理工具&#xff0c;它被设计用于处理已编译的Java类。ASM不是生成和转变已编译的Java类的唯一工具&#xff0c;但它是最新且最有效的工具之一。特点是体积小&a…

wsl的图像化实现,在wsl中启动浏览器

最近在学习wsl&#xff0c;原本我看以前的教程说wsl和vmware的区别有一点就是&#xff0c;wsl只能使用命令行&#xff0c;而vmware可以实现图像化&#xff0c;结果我在 microsoft 官方发现现在的wsl 2已经实现了 GUI 界面&#xff0c;所以就来记录一下吧。 wsl 的 GUI 实现 首…

web后端-请求响应

概述 我们之前在Spring写的 Java类&#xff0c;因为没有继承任何的接口 所以tomcat其实是不识别的&#xff0c;也不能直接运行 但是tomcat识别JavaEE的一项规范-Servlet,因为tomcat就相当于一个Servlet容器 SpringBoot底层提供了一个DisPatcherServlet类(实现了servlet接口)…

【linux】 安装 java 环境

目录 1.检查linux 下是否安装java(jdk)环境2.查看 linux 的操作系统版本3.下载jdk4.新建java文件夹用于安装jdk5.将下载到本地的jdk压缩包上传到linux服务器6.配置环境变量 1.检查linux 下是否安装java(jdk)环境 可通过下面五条命令来查看linux 系统是否安装了java 环境 1、jav…

建筑行业为什么要数字化转型?

建筑行业为什么要数字化转型&#xff1f; 建筑行业作为国民经济的重要支柱产业之一&#xff0c;其生产过程繁琐、复杂&#xff0c;且产业链条长&#xff0c;涉及众多领域。 然而&#xff0c;目前传统的建筑模式已经无法适应行业的发展需求&#xff0c;建筑行业的数字化转型已…

java SimpleDateFormat和Calendar日期类

目录 一、SimpleDateFormat使用二、Calendar使用 一、SimpleDateFormat使用 使用Date直接输出日期时&#xff0c;是使用系统默认的格式输出&#xff0c;所以需要使用SimpleDateFormat来格式化日期。 那么SimpleDateFormat类怎么使用呢&#xff0c;我们需要先了解此类的格式化符…

8.Java面向对象---类、属性和方法

Java面向对象—类、属性和方法 在生活中&#xff0c;说到类&#xff0c;可以联想到类别&#xff0c;同类&#xff0c;会想到一类人&#xff0c;一类事物等等。而这一类人或事物都是具有相同特征或特点和行为的&#xff0c;我们根据不同的特征或特点和行为将他们归类或分类。同…

Java多线程

一&#xff1a;进程与线程 概述&#xff1a;几乎任何的操作系统都支持运行多个任务&#xff0c;通常一个任务就是一个程序&#xff0c;而一个程序就是一个进程。当一个进程运行时&#xff0c;内部可能包括多个顺序执行流&#xff0c;每个顺序执行流就是一个线程。 进程&#x…

Faster-RCNN代码解读6:主要文件解读-中

Faster-RCNN代码解读6&#xff1a;主要文件解读-中 前言 ​ 因为最近打算尝试一下Faster-RCNN的复现&#xff0c;不要多想&#xff0c;我还没有厉害到可以一个人复现所有代码。所以&#xff0c;是参考别人的代码&#xff0c;进行自己的解读。 ​ 代码来自于B站的UP主&#xff…

【Linux系统】理解Linux中进程间通信

Linux进程间通信 1 进程间通信的介绍1.1为什么要有进程间通信1.2 为什么能进程间通信 2 进程间通信的框架2.1 进程间通信机制的结构2.2 进程间通信机制的类型2.2.1 共享内存式2.2.2 消息传递式 2.3 进程间通信的接口设计 3 进程间通信机制简介4 详细讲解进程间通信部分机制&…

文献管理软件Endnote、Mendeley、Zotero比较及选择,Zotero基础使用技巧

引言 大家好&#xff0c;我是比特桃。日常开发的项目分为两种&#xff0c;一种是成熟化的工程项目&#xff0c;只需要与具体的业务紧密结合及应用&#xff0c;难点也比较偏向于软件工程或者互联网高并发的方向。这种项目我们通常不会选择去查文献去寻找问题的解决办法&#xf…

Altium Designer 20 导出 Gerber 制造文件流程及注意事项

一、导出 Gerber 流程 设置原点&#xff1a;在Edit菜单中选择Origin&#xff0d;Set &#xff08;快捷键E-O-S&#xff09;定好原点&#xff0c;一般放在左下角附近即可。 放置分孔图表&#xff1a;在Place菜单中选择String放置“.Legend”&#xff08;快捷键P-S&#xff09;…

【java】maven引用外部 jar 包,以RXTXcomm.jar为例

目录 1.作为资源文件夹内的资源引用2.将jar包手动安装到maven仓库 工具&#xff1a;IntelliJ IDEA 2020.2.3 x64 1.作为资源文件夹内的资源引用 1.在项目根路径新建文件夹lib, 将资源文件复制到该文件夹。 2.将文件夹设置为资源文件夹&#xff1a;选中文件夹lib右键 -> Mak…

Activity启动模式

Activity的启动模式 首先activity启动之后是放在任务栈中的&#xff0c;task stack&#xff0c;既然是栈&#xff0c;遵循先进后出原则。有玩家比喻oncreate是入栈&#xff0c;onDestroy是出栈。 同一个APP中&#xff0c;不同的activity可以设置为不同的启动模式。在manifest…

【Kafka】SASL认证的Kafka客户端代码示例(spring-kafka和原生客户端)

文章目录 spring-kafka原生客户端Tips spring-kafka 添加依赖&#xff1a; <dependency><groupId>org.springframework.kafka</groupId><artifactId>spring-kafka</artifactId><version>2.6.3</version></dependency>添加spr…

【springcloud 微服务】Spring Cloud Alibaba Nacos使用详解

目录 一、前言 二、nacos介绍 2.1 什么是 Nacos 2.2 nacos 核心能力 2.2.1 服务发现和服务健康监测 2.2.2 动态配置服务 2.2.3 动态 DNS 服务 2.2.4 服务及其元数据管理 2.2.5 nacos生态地图 2.3 与其他配置中心对比 三、nacos快速部署 3.1 获取安装包 3.2 修改脚…

电阻器的原理、类型、参数以及生活中常见的应用

电阻器是电子电路中最基本的元件之一&#xff0c;它的作用是限制电流流过的大小&#xff0c;在电子电路中广泛应用于电流控制、电压分压、信号衰减等方面。在本文中&#xff0c;我们将详细介绍电阻器的原理、类型、参数以及生活中常见的应用。 一、电阻器的原理 电阻器是一种…

go语言切片做函数参数传递+append()函数扩容

go语言切片函数参数传递append()函数扩容 给你二叉树的根节点 root 和一个整数目标和 targetSum &#xff0c;找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。 二叉树递归go代码&#xff1a; var ans [][]int func pathSum(root *TreeNode, targetSum int) ( [][…

ActiveMQ使用(四):在JavaScript中发送的MQTT消息在SpringBoot中变为字节数组

ActiveMQ使用(四):在JavaScript中发送的MQTT消息在SpringBoot中变为字节数组 1. 问题描述 JmsListener(destination "test_producer", containerFactory "topicListenerContainer")public void receiveTestProducer(String message) throws JMSExceptio…