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