使用css变量实现前端无刷新切换主题

项目使用的是Vue3+viewUI前端框架,该框架使用的主要less颜色变量有

less 复制代码
// Color #2d8cf0
@primary-color: #036db7; //用于导航、重要按钮
@info-color: #55aeee;
@success-color: #19be6b;
@processing-color: @primary-color;
@warning-color: #ff9a09; //用于重要提示按钮
@error-color: #f85850; //用于重要警示按钮
@normal-color: #e6ebf1;
@link-hover-color: tint(@primary-color, 20%);
@link-active-color: shade(@primary-color, 5%);
@selected-color: fade(@primary-color, 90%);
@tooltip-color: #fff;
@subsidiary-color: #dddddd;
@rate-star-color: #f5a623;
@white: #fff;
@black: #000;

//font-color
@main-font-color: #000; //页面中文字主色 用于重要文字  如标题、短文本等
@assist-font-color: #606266; //用于辅助文字如导航未选文字等
@des-font-color: #909296; //用于描述性文字如选课时间、创建时间等

从中可以抽离出一种基础颜色,6中根据基础色计算的配色,从css文件中预先定义好css变量,方便后面用js直接覆盖变量的值

css 复制代码
:root{
    --theme: #036db7;
    --fade90: rgba(3,109,183,0.9);
    --fade20: rgba(3,109,183,0.2);
    --shade5: #368a e;
    --tint20: #368bc6;
    --tint80: #cde2f1;
    --tint90: #e6f1f8;
}

定义切换主题的js方法,设置主题与还原主题app.config.globalProperties.$initThemeColor为vue3定义全局变量的方式

javascript 复制代码
// 设置主题公共函数 defaultColor 为rgba模式值
    app.config.globalProperties.$initThemeColor=function(defaultColor){
        const value = defaultColor.replace('rgba(', '').replace(')', '').split(',');
        var themeObj = {
            theme: value.map(Number), //主题原色
            fade90: value.map(Number), //90%透明
            fade20: value.map(Number), //20%透明
            shade5: value.map(Number), //与黑色混合5%
            tint20: value.map(Number), //与白色混合20%
            tint80: value.map(Number), //与白色混合80%
            tint90: value.map(Number), //与白色混合90%
        };

        // 仿fade函数
        themeObj.fade90[3] = .9;
        themeObj.fade20[3] = .2;

        // 仿shade函数和tint函数
        for(let i=0;i<3;i++){
            themeObj.shade5[i] = Math.ceil(themeObj.shade5[i]-themeObj.shade5[i]*0.05);
            themeObj.tint20[i] = Math.ceil(themeObj.tint20[i]+(255*0.2)-(themeObj.tint20[i]*0.2));
            themeObj.tint80[i] = Math.ceil(themeObj.tint80[i]+(255*0.8)-(themeObj.tint80[i]*0.8));
            themeObj.tint90[i] = Math.ceil(themeObj.tint90[i]+(255*0.9)-(themeObj.tint90[i]*0.9));
        }

        // 修改css原生变量
        for(let key  in themeObj){
            document.documentElement.style.setProperty('--'+key,'rgba('+themeObj[key]+')');
        }
    }

    // 还原主题
    app.config.globalProperties.$resetThemeColor=function(){
        const defaultCssVar={
            theme: '#036db7',
            fade90: 'rgba(3,109,183,0.9)',
            fade20: 'rgba(3,109,183,0.2)',
            shade5: '#0368ae',
            tint20: '#368bc6',
            tint80: '#cde2f1',
            tint90: '#e6f1f8',
        }
        for(let key  in defaultCssVar){
            document.documentElement.style.setProperty('--'+key,defaultCssVar[key]);
        }
    }

缓存中预埋一个颜色值,main.js初始化主题

scss 复制代码
//初始化主题色
if(localStorage.themeColor){
	app.config.globalProperties.$initThemeColor(localStorage.themeColor);
}else{
	app.config.globalProperties.$resetThemeColor();
}

首页新增一个选择颜色的功能

ini 复制代码
changeTheme(color){
            if(color.length > 0){
                this.$initThemeColor(color);
            }else{
                this.$resetThemeColor();
            }
            color = color.length > 0 ? color : 'rgba(3,109,183,1)';
            localStorage.themeColor=color;
            this.themeColor=color;
        }

最后将框架css源码里面的对应颜色手动替换为上面的css变量,改完之后在项目根目录的index.html中引入该样式文件就可以了

实现的效果

相关推荐
LeeYaMaster4 分钟前
15个例子熟练异步框架 Zone.js
前端·angular.js
evelynlab7 分钟前
打包原理
前端
拳打南山敬老院1 小时前
Context 不是压缩出来的,而是设计出来的
前端·后端·aigc
用户3076752811271 小时前
💡 从"傻等"到"流淌":我在AI项目中实现流式输出的血泪史(附真实代码+深度解析)
前端
bluceli1 小时前
前端性能优化实战指南:让你的网页飞起来
前端·性能优化
SuperEugene1 小时前
Vue状态管理扫盲篇:如何设计一个合理的全局状态树 | 用户、权限、字典、布局配置
前端·vue.js·面试
没想好d1 小时前
通用管理后台组件库-9-高级表格组件
前端
阿虎儿1 小时前
React Hook 入门指南
前端·react.js
核以解忧1 小时前
借助VTable Skill实现10W+数据渲染
前端
WangHappy1 小时前
不写 Canvas 也能搞定!小程序图片导出的 WebView 通信方案
前端·微信小程序