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

文章介绍了uniapp中使用scss变量和require动态引入的方式来实现主题切换的第二种方法,通过定义不同主题的scss文件并维护独立的颜色变量,提高了扩展性和维护性。这种方法虽然优于第一种(vuex),但在某些平台可能存在兼容问题。
摘要由CSDN通过智能技术生成

在上一篇 “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主题切换的方式,有问题欢迎大家留言交流。

UniApp中定义全局变量可以通过使用SCSS实现。首先,你需要在uni.scss文件中引入一个variable.scss文件,可以使用以下代码: ```scss // 引入公共scss变量文件 @import './static/css/variable.scss'; ``` 接下来,你需要在App.vue文件中的style标签中添加lang="scss"属性,并在第一行引入uview-ui的index.scss文件以及其他需要的公共css文件,如base.css、common.scss和iconfont.css。可以使用以下代码: ```vue <style lang="scss"> /* 注意要写在第一行,同时给style标签加入lang="scss"属性 */ @import "uview-ui/index.scss"; /*每个页面公共css */ @import './static/css/base.css'; /* scss公共类 */ @import './static/css/common.scss'; @import './static/fonts/iconfont.css'; </style> ``` 接下来,你可以在common.scss文件中使用@import指令引入variable.scss文件,并定义公共的样式类。例如,你可以使用以下代码定义一个color-primary类和一个bg-primary类,其中使用了variable.scss文件中定义的$primary-color变量: ```scss @import './variable.scss'; // 引入公共scss变量文件 // 公共类 .color-primary { color: $primary-color; } .bg-primary { background-color: $primary-color; color: #fff; } ``` 这样,你就成功在UniApp中定义了全局的SCSS变量和样式类。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [uniapp 添加scss全局变量、scss公共类](https://blog.csdn.net/qq_40146789/article/details/124835164)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

新新领域

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值