• uniapp主题切换功能的第二种实现方式(scss变量+require)


    在上一篇 “uniapp主题切换功能的第一种实现方式(scss变量+vuex)” 中介绍了第一种如何切换主题,但我们总结出一些不好的地方,例如扩展性不强,维护起来也困难等等,那么接下我再给大家介绍另外一种切换主题的方法“scss变量+require”的方式

    在介绍如何使用前,先看下最后的效果,以便大家能更好的理解,下面是效果图:

    除了图上的这个页面切换了外,整体项目都有主题色的切换,具体效果可扫码自行查看。

    接下来详细介绍下第二种实现方式

    实现原理

    定义两套主题色(多套再自己加)theme-dark.scss、theme-light.scss,每套主题色维护着自己的颜色,通过require动态引入scss的形式引入当前主题,从而达到切换主题的目的

    第一步:创建不同主题色

    创建白天与夜晚模式

    创建白天模式

    common/theme/theme-dark.scss

    /* 切换主题主要切换的是  整体背景色、区块背景色、文字颜色等 */
    
    // 页面主题
    .theme-page{
    	background-color: #333 !important;
    	// 文字颜色
    	.theme-color{
    		color: #FFF !important;
    	}
    	// 区块主题色
    	.theme-block{
    		background-color: #FFFFFF !important;
    		.theme-color{
    			color: #000 !important;
    		}
    	}
    }
    
    // 如果想单独给个人中心设置一个主题色
    .theme-user-page{
    	background-color: #1a1a1a !important;
    	// 文字颜色
    	.theme-color{
    		color: #FFF !important;
    	}
    	// 区块主题色
    	.theme-block{
    		background-color: #FFFFFF !important;
    		.theme-color{
    			color: #000 !important;
    		}
    	}
    }
    

    创建夜间模式

    common/theme/theme-light.scss

    /* 切换主题主要切换的是  整体背景色、区块背景色、文字颜色等 */
    
    // 页面主题
    .theme-page{
    	background-color: #FFF !important;
    	// 文字颜色
    	.theme-color{
    		color: #333 !important;
    	}
    	// 区块主题色
    	.theme-block{
    		background-color: #999 !important;
    		.theme-color{
    			color: #333 !important;
    		}
    	}
    }
    
    // 如果想单独给个人中心设置一个主题色
    .theme-user-page{
    	background-color: #F2F2F2;
    	// 文字颜色
    	.theme-color{
    		color: #666 !important;
    	}
    	// 区块主题色
    	.theme-block{
    		background-color: #999 !important;
    		.theme-color{
    			color: #000 !important;
    		}
    	}
    }
    

    东西多了的情况,例如有5套主题色,分开不是很好维护,所以

    可以考虑把颜色值独立出去

    改进:独立主题色

    定义_theme.scss

    $themes: (
    	// 白天模式
        light:(
            page: (
                background-color: #fff,
                color: (
                    color: #333,
                ),
                block: (
                    background-color: #333,
                    color: (
                        color: #fff,
                    ),
                ),
            ),
            user-page: (
                background-color: #f2f2f2,
                color: (
                    color: #666,
                ),
                block: (
                    background-color: #999,
                    color: (
                        color: #000,
                    ),
                ),
            ),
        ),
    	// 夜间模式
        dark:(
            page: (
                background-color: #333,
                color: (
                    color: #fff,
                ),
                block: (
                    background-color: #fff,
                    color: (
                        color: #000,
                    ),
                ),
            ),
            user-page: (
                background-color: #1a1a1a,
                color: (
                    color: #fff,
                ),
                block: (
                    background-color: #FFFFFF,
                    color: (
                        color: #000,
                    ),
                ),
            ),
        )
    );
    

    第二步:处理主题色

    通过混入生成不同主题样式,代码如下

    @mixin map-to-class($map, $divider: "-", $select: ".theme", $isRoot: false, $root-select: ".theme") {
        $select: if($select== "" and &, &, $select);
        @each $k, $v in $map {
            $currSelect: if($isRoot, #{$root-select}#{$divider}#{$k}, #{$select}#{$divider}#{$k});
            #{$currSelect} {
                @if type-of($v) ==map {
                    @include map-to-class($v, $divider, "", true) {
                        @content;
                    }
                } @else {
                    @at-root #{$select} {
                        #{$k}: $v !important;
                    }
                }
            }
        }
    }
    
    @each $key, $mode in $themes {
        @if $key== "light" {
            @include map-to-class($mode);
        }
    }
    // 或
    @each $key, $mode in $themes {
        @if $key== "dark" {
            @include map-to-class($mode);
        }
    }
    

    大家可以用sass编辑器看一下最终的样式是什么样的

    第三步:App.vue动态引入

    在App.vue里面通过require动态引入主题,当前每次切换主题的时候要把当前主题数据进行保存。

    onLaunch: function() {
        let theme = uni.getStorageSync('theme') || 'light';
        // import `@/common/theme/theme-${mode}.scss`;  //记住不能import哦
        require(`@/common/theme/theme-${theme}.scss`);
    },
    // ......
    

    这样就实现了动态引入

    以后只须要维护_theme.scss即可

    最后测试

    测试代码:

    <template>
    	<view class="tpf-page theme-page">
    		<text class="theme-color">订单text>
    		<view class="theme-block block flex flex-align-center flex-pack-center">
    			<text class="theme-color">板块里面的文本text>	
    		view>
    		<view class="flex flex-align-center flex-pack-justify change-theme">
    			<text class="button" @tap="changeTheme('light')">白天模式text>
    			<text class="button dark" @tap="changeTheme('dark')">夜间模式text>
    		view>	
    	view>
    template>
    
    <script>
    export default{
    	data(){
    		return {
    			
    		}
    	},
    	methods:{
    		changeTheme(mode){
    			uni.setStorageSync('theme',mode);
    			setTimeout(()=>{
    				location.reload();
    			},200);
    		}
    	},
    	onReady() {
    		let theme = uni.getStorageSync('theme') || 'dark';
    		if(theme == 'dark'){
    			// 动态设置导航条颜色
    			uni.setNavigationBarColor({
    				frontColor:'#ffffff',
    				backgroundColor:'#333333'
    			});
    			
    			// 动态设置tabbar样式
    			uni.setTabBarStyle({
    				backgroundColor:'#333333',
    				color: '#FFF',
    				selectedColor: '#0BB640',
    				borderStyle: 'white'
    			});
    		}else{
    			// 动态设置导航条颜色
    			uni.setNavigationBarColor({
    				frontColor:'#000000',
    				backgroundColor:'#FFFFFF'
    			});
    			
    			// 动态设置tabbar样式
    			uni.setTabBarStyle({
    				backgroundColor:'#FFFFFF',
    				color: '#333',
    				selectedColor: '#0BB640',
    				borderStyle: 'black'
    			});
    		}
    	}
    }
    script>
    
    <style lang="scss" scoped>
    .block{
    	width: 710rpx;
    	height: 300rpx;
    	margin: 20rpx 0;
    }
    .change-theme{
    	width: 400rpx;
    }
    .button{
    	background-color:#FFF;
    	color: #000;
    	padding: 20rpx;
    }
    .dark{
    		background-color: #000;
    		color: #FFF;
    }
    style>
    

    在这里导航栏与tabbar都是通过手动设置的,因为必须是js操作,所以样式不能去读css,为了方便,我们也可以定义一个theme.js专门来维护导航栏与tabar样式

    补充theme.js

    theme.js定义主题案例代码:

    const themes = {
    	light:{
    		navBar:{
    			bgColor:'#000',
    			color:'#FFF'
    		},
    		tabBar:{
    			bgColor:'#000',
    			color:'#FFF',
    			borderStyle:'black'
    		}	
    	},
    	dark:{
    		navBar:{
    			bgColor:'#FFF',
    			color:'#000'
    		},
    		tabBar:{
    			bgColor:'#f2f2f2',
    			color:'#333',
    			borderStyle:'white'
    		}
    	}
    }
    
    let mode = 'dark'
    
    export default themes[mode];
    

    页面就可以通过引入这个js,通过当前主题引入相关的配置即可。这样方便统一维护与管理 。

    最后总结

    scss变量+require的方式明显比第一种要好,减少了页面与主题的耦合度,维护起来也方便

    但出于一些性能上的问题(官方回答),在某些平台或版本已经取消了require动态引入样式的功能,因此这个是有兼容问题的。

    这就是我给大家介绍的第二种unippa主题切换的方式,有问题欢迎大家留言交流。https://www.cnblogs.com/top8/p/17460706.html

  • 相关阅读:
    华三中小企业组网
    通关GO语言20 协作开发:模块化管理为什么能够提升研发效能?
    pycharm安装jupyter,用德古拉主题,但是输入行全白了,看不清,怎么办?
    Cherno C++视频课程-学习笔记
    51单片机mq3酒精浓度检测mq3酒驾醉驾检测酒精报警ADC0832采集
    Springboot毕设项目物品捎带系统41pudjava+VUE+Mybatis+Maven+Mysql+sprnig)
    基于SSM框架实现学生管理系统
    二刷算法训练营Day45 | 动态规划(7/17)
    性能测试常见分类
    2023-06-17:说一说redis中渐进式rehash?
  • 原文地址:https://www.cnblogs.com/top8/p/17463028.html