在上一篇 “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

uniapp主题切换功能的第二种实现方式(scss变量+require)的更多相关文章

  1. 使用Typescript重构axios(十九)——请求取消功能:实现第二种使用方式

    0. 系列文章 1.使用Typescript重构axios(一)--写在最前面 2.使用Typescript重构axios(二)--项目起手,跑通流程 3.使用Typescript重构axios(三) ...

  2. 基于.NetCore开发博客项目 StarBlog - (14) 实现主题切换功能

    系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...

  3. python_并发编程——多进程的第二种启动方式

    1.多进程的第二种启动方式 import os from multiprocessing import Process # 创建一个自定义类,继承Process类 class MyProcess(Pr ...

  4. WEB安全实战(五)XSS 攻击的第二种解决方式(推荐)

    序 说到 XSS 攻击,前边已经有两篇文章在讲这个事了,这次又拿出来说,主要是针对近期工作中的一些新的问题.那么之前是怎么解决问题的呢?为什么又要换解决方式?以下就具体的跟大家分享一下. 旧方案 公司 ...

  5. ANDROID_MARS学习笔记_S02_008_ANIMATION第二种使用方式:xml

    一.简介 二.代码1.res\anim下的xml(1)alpha.xml.xml <?xml version="1.0" encoding="utf-8" ...

  6. iOS开发之App主题切换完整解决方案(Swift版)

    本篇博客就来介绍一下iOS App中主题切换的常规做法,当然本篇博客中只是提到了一种主题切换的方法,当然还有其他方法,在此就不做过多赘述了.本篇博客中所涉及的Demo完全使用Swift3.0编写完成, ...

  7. Android主题切换—夜间/白天模式探究

    现在市面上众多阅读类App都提供了两种主题:白天or夜间. 上述两幅图片,正是两款App的夜间模式效果,所以,依据这个功能,来看看切换主题到底是怎么实现的(当然现在github有好多PluginThe ...

  8. spring框架总结(03)重点介绍(Spring框架的第二种核心掌握)

    1.Spring的AOP编程 什么是AOP?  ----- 在软件行业AOP为Aspect Oriented Programming  也就是面向切面编程,使用AOP编程的好处就是:在不修改源代码的情 ...

  9. 使用Typescript重构axios(二十)——请求取消功能:实现第一种使用方式

    0. 系列文章 1.使用Typescript重构axios(一)--写在最前面 2.使用Typescript重构axios(二)--项目起手,跑通流程 3.使用Typescript重构axios(三) ...

  10. 基于Metronic的Bootstrap开发框架经验总结(11)--页面菜单的几种呈现方式

    在常规的后台管理系统或者前端界面中,一般都有一个导航菜单提供给用户,方便选择所需的内容.基于Metronic的Bootstrap开发框架,是整合了Metroinc样式,以及Boostrap组件模块的内 ...

随机推荐

  1. 微信小程序登录页左上角的home图标如何隐藏?wx.hideHomeButton()不生效?

    在做微信小程序时,我们一般都会在app.js中去判断当前用户是否已经登录,如果已经登录,会直接跳转到小程序的首页.如果未登录那么直接跳转登录页. 此时我们需要把首页首页作为微信小程序的pages列表中 ...

  2. 推荐三款 Mac 上的理财神器 iCompta、Rublik、UctoX

    今天推荐三款理财神器,像个人的话可以使用 iCompta(个人财务管理)一款软件就好了,但有些朋友可能有关注汇率的需求,可以使用 Rublik(汇率动态),还有一些小伙伴可能有自己的公司等原因财务量较 ...

  3. Java19新特性

    本文已经收录到Github仓库,该仓库包含计算机基础.Java基础.多线程.JVM.数据库.Redis.Spring.Mybatis.SpringMVC.SpringBoot.分布式.微服务.设计模式 ...

  4. Spring事务——传播性

    传播性 事务传播行为是为了解决业务层方法之间互相调用的事务问题,当一个事务方法被另一个事务方法调用时,事务该以何种状态存在?例如新方法可能继续在现有事务中运行,也可能开启一个新事务,并在自己的事务中运 ...

  5. AIArena Frontend 初步练习

    尝试对starter项目的页面进行改变 修改侧边栏,只留下最上面的「仪表盘」和「列表页」两个大模块 in SideNav.vue the code for the sidebar menu is: & ...

  6. [工具/Maven]Maven工程目录结构 | Maven自动构建骨架(maven-archetype)中quickstart与webapp的区别

    1 maven-archetype-quickstart 1.1 IDEA中的前期准备 1.2 自动构建后 ↓pom.xml↓ <?xml version="1.0" enc ...

  7. 四月二十四号java基础知识

    1.输入输出是指程序与外部设备或其他计算机进行交互的操作2.流(stream)是指计算机各部件之间的数据流动流的内容上划分:流分为字节流和字符流3.输入流:将数据从外设或外存(如键盘.鼠标.文件等)传 ...

  8. 一文吃透Arthas常用命令!

    Arthas 常用命令 简介 Arthas 是Alibaba开源的Java诊断工具,动态跟踪Java代码:实时监控JVM状态,可以在不中断程序执行的情况下轻松完成JVM相关问题排查工作 .支持JDK ...

  9. Windows服务器重启注意事项

    windows作为服务器有它的优势,但是相比于基于linux作为服务器来说,它不够稳定,这里的windows服务器作为服务器有各种版本,windows2012,2008,甚至还有2003,XP的系统, ...

  10. PHPCMSV9 单文件上传功能代码

    后台有"多文件上传"功能,但是对于有些情况,我们只需要上传一个文件,而使用多文件上传功能上传一个文件,而调用时调用一个文件太麻烦了. 所以我就自己动手,参考其他字段类型的网站,研究 ...