后面我曾经给大家介绍了两种主题切换的形式,每种形式各有本人的劣势与毛病,例如“scss变量+vuex”形式兼容好但不好保护与扩大,“scss变量+require”形式好保护但兼容不好,还不分明的可点上面链接中转理解一下
uniapp主题切换性能的第一种实现形式(scss变量+vuex)
uniapp主题切换性能的第二种实现形式(scss变量+require)
了解了这些能力更好的了解我接下来给大家总结的。
最初做的这个能兼容所有平台的主题切换成果,大家能够微信扫码一睹为快,切换性能在”集体核心“那里(模拟的b站),目前分白天与夜间模式
接下来就给大家介绍一下如何做一个兼容好,又好保护的主题切换性能
解决思路
uniapp利用在做开发的时候,拆分页面其实就分两大部分,主体局部+导航栏与tabbar
为什么要这么分,因为主体局部的款式通常是一般css代码管制的,而导航栏+tabBar(例如原生的状况)须要通过api去批改。而css与js目前还不能齐全互通。
因而要做全平台兼容同样须要保护主体局部的款式(纯css)与导航栏+tabBar局部的款式(js),明确了原理,接下来就上代码
第一局部:全局“主体局部”主题款式
这样其实就是之前讲过的,上代码
定义common/css/_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); }}
其实能够循环一次性输入,这个交给你们了。。。
页面应用
<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>
这里次要通过加theme前缀(你本人能够改成想要的)的类theme-page
、theme-color
、theme-block
等等等的形式给内容块加背景,给字体加色彩等
这样页面是不是就很好保护,不同色彩的页面,你只须要在_theme.scss主题外面进行增加或批改后,在页面增加回应的theme-xxx类即可。
这样就解决了主体局部的款式主题切换问题。
第二局部:全副“导航栏+tabBar”主题款式
因为这部分波及到原生操作,须要用到api,所以必须是js来保护主题款式
定义theme.js
// 定义导航栏 与 tabbar 主题色const themes = { light:{ navBar:{ backgroundColor:'#FFF', frontColor:"#000000" }, tabBar:{ backgroundColor:'#FFF', color:'#333', selectedColor:'#0BB640', borderStyle:'white' } }, dark:{ navBar:{ backgroundColor:'#333', frontColor:"#ffffff" }, tabBar:{ backgroundColor:'#333', color:'#fff', selectedColor:'#0BB640', borderStyle:'black' } }}export default themes;
第一种应用形式vue.prototype的全局挂载(不举荐)
不举荐的起因:::有兼容问题!!!
mian.js
//引入主题import themes from '@/common/theme/theme.js';....//全局挂载Vue.prototype.$themes = themes;
第二种应用形式:Vuex / globalData
为什么应用这两种,因为他们是目前官网兼容所有平台的,这里我只介绍Vuex的形式
创立store.js
import Vue from 'vue'import Vuex from 'vuex'// 引入主题import themes from '@/common/theme/theme.js';Vue.use(Vuex); const store = new Vuex.Store({ state: { theme:themes[uni.getStorageSync('theme') || 'light'] }, getters: { }, mutations: { updateTheme(state,mode = 'light'){ state.theme = themes[mode]; } }}) export default store
页面应用
创立好store之后,就能够在页面外面动静设置导航栏与tabBar了,具体大家本人去依据爱好封装。
onReady(){ //Vuex的形式 // 设置导航条 uni.setNavigationBarColor(this.$store.state.theme.navBar); // 设置tabbar uni.setTabBarStyle(this.$store.state.theme.tabBar); },
如何实现切换
更新就是更改store的状态,因为他是全局的,所有页面都能利用到
this.$store.commit("updateTheme",mode);// 设置导航条uni.setNavigationBarColor(this.$store.state.theme.navBar);// 设置tabbaruni.setTabBarStyle(this.$store.state.theme.tabBar);
最初总结
要想实现全端兼容,必定所有的代码都要思考到兼容所有平台,因为做的时候要就思考到。
主题切换对于利用来说是一个大工程,原理给大家说了,实现部署还须要大家好好的思考,其中扩展性,可维护性等都必须当时思考的,不然我的项目必定做不大。
想看我做的最终成品怎么样,能够扫码看看
有什么做得不好的,或没有思考到位的,欢送大家留言探讨交换,独特学习提高。