使用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中引入该样式文件就可以了

实现的效果

相关推荐
小雨下雨的雨几秒前
蜡笔小画家鸿蒙PC用Electron框架 - 儿童学画蜡笔画技术实现详解
前端·javascript·华为·electron·前端框架·交互·鸿蒙系统
天蓝色的鱼鱼几秒前
别只拿 Playwright 写测试,这三个野路子用法才是真香
前端
SoaringHeart3 分钟前
Flutter进阶|源码修改:DecorationImage 添加网络图片占位图
前端·flutter
小新1108 分钟前
vue 实战项目 天气查询
前端·javascript·vue.js
7yue9 分钟前
用 TypScript 学习 Claude Code
前端·typescript·claude
Rain50910 分钟前
实战:搭建 AI Code Review 自动化流水线
前端·人工智能·git·ci/cd·自动化·ai编程·代码复审
Nian_Baikal10 分钟前
从零搭建离线地图服务:Nginx + Cesium/Leaflet 实战指南
前端
问心无愧051310 分钟前
ctf show web入门99
android·前端·笔记
用户6000718191012 分钟前
【翻译】CSS 与 JavaScript:动画性能该怎么选
前端