uniapp主题切换功能的第二种实现方式(scss变量+require)
Posted 敲出NB的人生
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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
前端切换主题
参考技术A 1.theme.scss2.vue.config.js 添加全局scss文件
3. App.vue 切换主题时 设置该属性
window.document.documentElement.setAttribute('data-theme', newVal);
以上是关于uniapp主题切换功能的第二种实现方式(scss变量+require)的主要内容,如果未能解决你的问题,请参考以下文章
创建对象的第二种方式:克隆clone,要实现Cloneable接口
创建线程的第二种方式------实现Runnable接口的方式