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