uni-app动态修改主题色的方法详解

目录
  • 前言
  • 一.uni.scss 使用方式
  • 二.暗黑主题
  • 三.自定义主题配置
    • 1.在根目录下新建 theme 文件夹
      • css-theme
      • uni.scss中引入
      • css-variate
      • cue-theme
      • main.js 导入
      • system-theme
    • 2.vuex 配置
      • index.js 全局导出
      • main.js中导入
    • 3.页面中使用
  • 四.黑夜 白天主题展示
  • 总结

前言

老是碰到初版制作完成没多久,就整一出说什么要更改整个项目的色彩体系。真的是宝宝心里苦啊!

起初都是通过uni项目自带的uni.scss中定义,在替换页面上对应的css。以便于达到一次性修改整体布局的样式。

一.uni.scss 使用方式

在该文件里定义: $名字 :颜色值;

使用时需要在 style 节点上加上 lang=“scss”

<style lang="scss" scoped>
    .bg {
        height: 120px;
        width: 100%;
        background-color: $uni-color-primary;
    }
</style>

该方法使用,适合单一颜色修改,一次修改全局统一。

二.暗黑主题

暗黑模式(Dark Mode),也被称为夜间模式或深色模式,是一种高对比度,或者反色模式的显示模式。是一种有利于在黑暗环境下观看手机的高对比度的模式。uni-app的暗黑模式,是帮助开发者完成自己应用的暗黑模式的一批配置和API。开发者可以参考本文实现自己应用的暗黑模式。

注:HBuilder X 3.6.9+ 支持 目前只支持深色和浅色

具体介绍看官网地址:uniapp.dcloud.net.cn/tutorial/da…

三.自定义主题配置

可自行定义多种主题配色,通过js动态修改导航栏等色彩。缺点在于,页面加载缓慢时前期会显示出原有的色彩。整体上不影响使用。

注:在APP 微信小程序 H5 都行

1.在根目录下新建 theme 文件夹

css-theme.scss 主题适配主要css

css-variate.scss 统一颜色值配置

cue-theme.js vue 混入js

system-theme.js 自定义的相关配置

css-theme

主要为使用sass切换主题,百度一下大部分都是按照以下配置,这里不过多介绍

注:uni中使用时 建议这个scss 在 uni.scss 中 引入该scss

/*
* @author: Jay
* @description: 通过监听 css 变量切换主题色
* @createTime: 2022-12-13 11:29:00
* @introduce: 需要在 uni.scss 中 引入该scss
*/

//统一配置色彩
@import "./css-variate.scss";

/*---------------------方法一 使用css 控制变量  ---------------------------*/
/*
    使用方法
    .css-theme {
        width: 100%;
        @include text-color();
        @include base-background();
        @include border-color();
        @include shadow-color();
    }
*/

/* 白天主题 颜色集合 */
$day-theme:(
    bg-color:$day-bg,
    text-color:$day-text,
    border-color: $day-border,
    shadow-color:$day-shadow
);

/* 夜间主题 颜色集合 */
$night-theme:(
    bg-color:$night-bg,
    text-color:$night-text,
    border-color: $night-border,
    shadow-color: $night-shadow
);

/* 玉红主题 颜色集合 */
$jade-theme:(
    bg-color:$jade-bg,
    text-color:$jade-text,
    border-color: $jade-border,
    shadow-color: $jade-shadow
);

//定义主题对象
$themes: (
  day-theme: $day-theme,
  night-theme: $night-theme,
  jade-theme: $jade-theme
);

// 生成主题背景色样式
@mixin base-background(){
    @each $themename , $theme in $themes {
        &.#{$themename} {
            background-color: map-get($map: $theme, $key: bg-color);
        }
    }
}

// 生成主题字体色样式
@mixin text-color(){
    @each $themename , $theme in $themes {
        &.#{$themename} {
            color: map-get($map: $theme, $key: text-color) !important;
        }
    }
}

// 生成主题边框色样式
@mixin border-color($opa: 1.0){
    @each $themename , $theme in $themes {
        &.#{$themename} {
            border-color: rgba(map-get($map: $theme, $key: border-color), $opa) !important;
        }
    }
}

// 生成主题阴影
@mixin shadow-color(){
    @each $themename , $theme in $themes {
        &.#{$themename} {
            box-shadow: 0 16rpx 32rpx rgba(map-get($map: $theme, $key: shadow-color), 0.4);
        }
    }
}

/*---------------------方法二 使用css 属性选择器  ---------------------------*/
/*
    使用方法
        <view class="padding-sm" :data-theme="cueTheme">
            暗黑模式-官方自带:(只支持 白天黑夜)
        </view>
*/

/* 白天主题 */
[data-theme='day-theme'] {
    background-color: $day-bg;
    color: $day-text;
    border-color: $day-border !important;
    shadow-color: $day-shadow;
}

/* 夜间主题 */
[data-theme='night-theme'] {
    background-color: $night-bg;
    color: $night-text;
    border-color: $night-border !important;
    shadow-color: $night-shadow;
}

/* 玉红主题 */
[data-theme='jade-theme'] {
    background-color: $jade-bg;
    color: $jade-text;
    border-color: $jade-border !important;
    shadow-color: $jade-shadow;
}

uni.scss中引入

/* 主题相关颜色 */
@import './theme/css-theme.scss';

css-variate

主要为配置主题所需css 颜色值,方便统一修改。

/*
	主题 统一配置色彩
*/

//页面背景色
$page-bg:var(--page-bg,#FFFFFF);

// 白天主题
$day-bg: #FFFFFF;
$day-text: #333333;
$day-border: #c8c7cc;
$day-shadow: #c8c7cc;

// 夜间主题
$night-bg: #292929;
$night-text: #FFFFFF;
$night-border: #c8c7cc;
$night-shadow: #FFFFFF;

// 玉红主题
$jade-bg: #c04851;
$jade-text: #FFFFFF;
$jade-border: #eea2a4;
$jade-shadow: #f1939c;

/*
	需要在js 中使用的css 导出
		APP 无法使用
		h5 微信小程序有值
*/

:export {
	dayBg: $day-bg;
	nightBg: $night-bg;
	jadeBg: $jade-bg;
}

cue-theme

主要使用 混入 (mixin) ,方便与在页面中复用相同的功能。

该方法主要调用vuex的数据 和 system-theme 中的方法

注:需要在main.js 导入该js

/*
 * @author: Jay
 * @description: 监听主题变化
 * @createTime: 2022-12-12 15:22:19
 */
import system from '../theme/system-theme'
import {
	mapMutations,
	mapGetters
} from 'vuex'
export default {
	install(Vue) {
		Vue.mixin({
			onShow() {
				//修改导航栏 底部 tab
				system.setSystemTheme(this.cueTheme)
				//获取缓存 背景色
				let bgColor = uni.getStorageSync('pageColor') || '';
				if (bgColor) {
					this.getSystemBg(bgColor)
				}
				//获取缓存 主题名字
				let themeType = uni.getStorageSync('themeType') || '';
				if (themeType) {
					this.cueGetTheme(themeType)
				}
				// 监听主题状态变化
				uni.onThemeChange((res) => {
					// console.log("监听主题状态变化", res.theme);
					//黑夜
					if (res.theme == 'dark') {
						this.cueGetTheme('night-theme')
					}
					//白天
					if (res.theme == 'light') {
						// 有多个主题时 判断 缓存是否为白色主题
						let type = uni.getStorageSync('themeType');
						if (type != 'day-theme') {
							this.cueGetTheme(type)
						} else {
							this.cueGetTheme('day-theme')
						}
					}
				});
			},
			computed: {
				// 获取vuex 主题参数
				...mapGetters({
					cueTheme: 'theme/theme',
					pageBg: 'theme/pageColor',
				}),
			},
			methods: {
				// 修改主题
				...mapMutations({
					cueGetTheme: 'theme/GET_THEME',
					themeCache: 'theme/SET_THEME_CACHE',
					pageColorCache: 'theme/SET_PAGE_COLOR'
				}),
				// 设置 全局背景色
				getSystemBg() {
					//从 主题列表 获取 页面颜色
					let bgColor = system.systemThemeBg(this.cueTheme)
					// console.log(bgColor);
					//缓存 已设置 背景色
					this.pageColorCache(bgColor)
				}
			}
		})
	}
}

main.js 导入

//监听主题变化
import theme from './theme/cue-theme.js'
Vue.use(theme)

system-theme

主要用来放置一些需要重复使用的js。可根据需求自行添加

注: themeList 为系统主题列表参数相关配置,用于全局设置系统导航栏,底部tab颜色值的存放。

注:其中导入 css-variate.scss 在app 没有相关数据返回,h5,微信小程序则有数据返回。其他平台自行测试。

/*
 * @author: Jay
 * @description: 主题相关配置
 * @createTime: 2022-12-12 17:45:09
 */

/*
	variables APP 拿不到值
	h5 微信小程序有值返回
*/
import variables from './css-variate.scss'
export default {
	/*
		系统主题列表
	*/
	themeList() {
		return [{
			title: "白天",
			name: "day-theme",
			navBg: variables.dayBg,
			navBgApp: "#FFFFFF",
			tabBg: "",
			tabSeleText: "",
			tabText: "",
		}, {
			title: "黑夜",
			name: "night-theme",
			navBg: variables.nightBg,
			navBgApp: "#292929",
			tabBg: "",
			tabSeleText: "",
			tabText: "",
		}, {
			title: "玉红",
			name: "jade-theme",
			navBg: variables.jadeBg,
			navBgApp: "#c04851",
			tabBg: "",
			tabSeleText: "",
			tabText: "",
		}]
	},
	//根据主题 返回背景色
	systemThemeBg(name) {
		let color = ''
		this.themeList().map((item, index) => {
			if (item.name === name) {
				color = item.navBgApp
			}
		})
		return color
	},
	//根据主题 修改系统 导航栏 底部 tab
	setSystemTheme(name) {
		this.themeList().map((item, index) => {
			if (item.name === name) {
				// 设置页面导航条颜色
				this.setNavigationColor(item.name, item.navBgApp)
				// 设置 tabBar 样式
				this.setTabBarColor(item.tabBg, item.tabSeleText, item.tabText)
			}
		})
	},
	/*
		设置页面导航条颜色
		name 主题名字  该颜色值只支持2种 故判断对于白天 为 #000 其他均为 #FFF
		bgClor 背景色  可以随意修改
	*/
	setNavigationColor(name, bgClor) {
		let navigationBar = {
			// 前景颜色值 仅支持 #ffffff 和 #000000
			frontColor: name == 'day-theme' ? "#000000" : "#ffffff",
			// 背景颜色值
			backgroundColor: bgClor || "#FFFFFF",
			// fail(err) {
			// 	console.error(err)
			// }
		}
		uni.setNavigationBarColor(navigationBar)
	},

	/*
		动态 设置 tabBar 样式
	*/
	setTabBarColor(bgColor, seleColor, color) {
		let tabBar = {
			// 背景色
			backgroundColor: bgColor || '#ffffff',
			// 文字选中时的颜色
			selectedColor: seleColor || '#3cc51f',
			// 文字默认颜色
			color: color || '#7A7E83',
		}
		uni.setTabBarStyle(tabBar)
	}
}

2.vuex 配置

使用vuex模块化开发(module)用于区分主题相关设置 与其他需求。

theme.js 模块

注:namespaced: true 主要为 cue-theme 用于模块化调用。缺少这个,在调用cue-theme中的方法时,拿不到所需参数

//主题相关配置
import system from '../../theme/system-theme'

const theme = {
	namespaced: true,
	state: {
		theme: "day-theme",
		//主题列表
		theme: system.themeList(),
		//页面背景色
		pageColor: "",
	},
	mutations: {
		//设置主题色
		GET_THEME(state, provider) {
			state.theme = provider
			//修改导航栏 底部 tab
			system.setSystemTheme(state.theme)
		},
		//设置主题缓存
		SET_THEME_CACHE(state, provider) {
			uni.setStorage({
				key: 'themeType',
				data: provider
			});
		},
		//设置主题缓存
		SET_PAGE_COLOR(state, provider) {
			state.pageColor = provider
			//缓存
			uni.setStorage({
				key: 'pageColor',
				data: provider
			});
		},
	},
	getters: {
		theme: state => state.theme,
		pageColor: state => state.pageColor
	},
	actions: {

	}
}

export default theme

index.js 全局导出

import Vue from "vue"
import Vuex from "vuex"
//登录
import logIn from "./modules/login.js"
//主题切换
import theme from "./modules/theme.js"

Vue.use(Vuex)
const store = new Vuex.Store({
	modules: {
		theme,
		logIn
	}
})

export default store

main.js中导入

//引入
storeimport store from 'store/index.js'
Vue.prototype.$store = store

3.页面中使用

class="conter" :style="{'--page-bg':pageBg}" 为该页面单独设置背景色 ,需要配合 page 设置页面高度使用

:data-theme="cueTheme" 给view设置data-theme属性,根据名字匹配对应颜色

:class="[cueTheme]" 设置对应的名字, css 中使用 @include text-color();

案例地址: gitee.com/jielov/uni-…

<!--
* @author: Jay
* @description: 动态修改主题色
* @createTime: 2022-12-12 14:55:31
 -->
<template>
	<view class="conter" :style="{'--page-bg':pageBg}">
		<view class="padding margin-bottom-xl css-theme" :class="[cueTheme]">
			<view class="text-lg text-center text-bold">
				暗黑模式
			</view>
			<view class="margin-top-sm" @click="openDoc">
				uni-app的暗黑模式。<text class="text-blue">点击查看官方文档</text>
			</view>
		</view>

		<view class="css-theme padding" :class="[cueTheme]">
			<view class="text-center text-bold text-lg">
				通过判断css 名字修改主题!!!
			</view>
			<view class="margin-tb-sm text-lg text-center">
				当前主题:{{cueTheme}}
			</view>
			<view class="margin-tb-sm text-lg text-center">
				当前页面背景色:{{pageBg}}
			</view>
			<view class="flex align-center justify-around">
				<button class="cu-btn round" @click="cssEditThemeBut('day-theme')">白天</button>
				<button class="cu-btn round" @click="cssEditThemeBut('night-theme')">黑夜</button>
				<button class="cu-btn round" @click="cssEditThemeBut('jade-theme')">玉红</button>
			</view>
		</view>

		<view class="padding margin-top-xl" :data-theme="cueTheme">
			<view class="text-center text-bold text-lg">
				通过 data-theme 判断 名字修改主题!!!
			</view>
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				url: 'https://uniapp.dcloud.net.cn/tutorial/darkmode.html#open-darkmode'
			};
		},
		onLoad() {
			console.log("当前主题:", this.cueTheme);
		},
		onShow() {},
		methods: {
			cssEditThemeBut(e) {
				//修改主题
				this.cueGetTheme(e)
				//设置主题缓存
				this.themeCache(e)
				//设置 全局背景色
				this.getSystemBg()
				// js自改变量值  h5 可用
				// document.getElementsByTagName('body')[0].style.setProperty('--page-bg', 'red');
			},
			openDoc() {
				// #ifdef APP
				plus.runtime.openWeb(this.url);
				// #endif
				// #ifdef H5
				let a = document.createElement('a');
				a.href = this.url;
				a.target = '__blank';
				a.click();
				a = null;
				// #endif
			}
		}
	}
</script>
<style>
	/* 全局背景色 */
	page {
		height: 100%;
	}
</style>
<style lang="scss" scoped>
	// 全局背景色
	.conter {
		height: 100%;
		background-color: $page-bg;
	}

	.css-theme {
		// border: 2px solid;
		@include text-color();
		@include base-background();
		@include border-color();
		@include shadow-color();
	}
</style>

四.黑夜 白天主题展示

总结

到此这篇关于uni-app动态修改主题色的文章就介绍到这了,更多相关uni-app动态修改主题色内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • uni-app禁用返回按钮/返回键的具体实现

    目录 前言 实现 具体演示代码 附:uni-app H5的返回拦截经验分享 总结 前言 使用uni-app开发原生应用时,遇到需求: 需要禁用物理返回按钮.手势返回. uni.navigateBack仍可使用. 实现 当前页面的onBackPress()中,禁用物理返回 pages.json中,去除当前页面的返回按钮 当前页面的mounted()中,隐藏当前页面的返回按钮(针对pages.json中设置无效的情况) 具体演示代码 1.当前页面中,在onBackPress()控制是否禁用返回按钮.

  • uni-app弹出层uni-popup使用及修改默认样式的方法实例

    uni-popup官方文档 我这里的背景是弹出一个选择规格的菜单.使用vue3+ts,使用组合式api 首先看看在vue3+ts+setup下的使用: <template> <!-- 定义一个按钮,用于打开弹出层 --> <view style="width: 200px"> <button @click="openSpecs">弹出</button> </view> <!-- 弹出层视图

  • uni-app使用swiper实现轮播图的方法

    目录 uni-app轮播图实现之swiper 补充:uniapp swiper 自定义轮播图指示点 总结 uni-app轮播图实现之swiper 首先在data中定义一个图片数据的对象数组 data() { return { rotation: [ { id: 1, url: 'https://imgcps.jd.com/ling4/100035927374/5Lqs6YCJ5aW96LSn/5L2g5YC85b6X5oul5pyJ/p-5bd8253082acdd181d02fa42/60f0

  • uni-app多环境部署解决方案详解

    目录 前言 尝试几种方式 解决方案 部署方式 获取接口 部署路径 命令行 其他 总结 前言 最近几周都在处理公司的移动业务,而为在后期能统一多端,解放自己,迎合公司的技术栈:选用了 uni-app 来开发.开发前期重新对公司移动业务做深入了解,重构大部分业务逻辑,也抽离出基础组件:但实际到部署的时候,出现来问题:由于现在只考虑 H5 端,部署和测试会出现多环境配置,但是我使用的 HBuilderX 工具创建的工程,所以只存在开发环境:development 和生产环境:production. 尝

  • 使用uni-app打包H5的图文教程

    1. 找到项目中 manifest.json --- H5 配置---运行时的基础路径, 将路径修改为 相对路径(./ ) 2. 修改完后,点击工具栏 --- 发行 --- 网站pc web或手机 h5 3. 弹出弹窗,修改网站标题与网站域名(网站域名取对应项目的域名,一般为https/http开头)填完后直接点击发行. 4. 点击发行后如图 5. 发行成功后,找到 unpackage --- dist --- build --- h5 文件夹, 在外部资源中打开,将 h5 文件夹打包成 zip

  • uni-app路由配置文件pages.json平台化拆分

    目录 对uni-app路由配置文件pages.json进行平台化拆分 例子: 优化思路: 过程: 对uni-app路由配置文件pages.json进行平台化拆分 背景:公司打造小程序矩阵化,以uni-app作为技术栈生成不同平台的小程序代码.小程序项目包含5个平台的代码,虽然是一份代码运行5个平台,但是各个平台又有差异,在代码里面需要做很多条件编译进行兼容处理.随着项目的壮大与页面的增多,控制路由的pages.json已经异常庞大且代码可读性差(想找一个页面需要找到上下文切换,浪费时间并且可能误

  • SpringBoot动态修改yml配置文件的方法详解

    目录 前言 具体实现 实现代码 测试 源码 总结 前言 记录下SpringBoot修改yml配置文件后无需重启服务的方式(打包后生效),效果如下: 具体实现 实现代码 pom.xml <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </d

  • python pandas修改列属性的方法详解

    使用astype如下: df[[column]] = df[[column]].astype(type) type即int.float等类型. 示例: import pandas as pd data = pd.DataFrame([[1, "2"], [2, "2"]]) data.columns = ["one", "two"] print(data) # 当前类型 print("----\n修改前类型:&quo

  • JavaScript React如何修改默认端口号方法详解

    问题 我们在使用React的时候经常会遇到这种情况,3000端口号被占用.有时候可以关掉3000端口,但更多时候,我们需要打开多个项目的时候,就必须要开启多个端口了.这时候就需要修改默认端口号了. 解决办法 修改默认端口号 具体做法 第一步:找到start.js文件 这个文件的位置在:node_modules文件夹下 -> react-scripts文件夹下 -> scripts文件夹下 -> start.js node_modules下 start.js文件 51行处修改,整个文件端口

  • JavaScript实现生成动态表格和动态效果的方法详解

    今天上午完成了Vue实现一个表格的动态样式,那么JavaScript代码能不能实现同样的效果呢?这样也可以学习一下JavaScript的语法,晚上试了一下,完全可以,效果一模一样. <!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="X-UA-Compatible" content="text/html; charset=utf-8">

  • vue 动态设置浏览器标题的方法详解

    目录 废话 正文 第一种 router/index.js 第二种 1.安装插件 2.main.js 引用 3.添加指令 笔记 总结 废话 平时设置浏览器标题是这样的 但vue是单页面应用,入口文件也只有一个html,只能设置一个标签,所以下面介绍两种常用的动态设置浏览器标签的方法 正文 第一种 使用浏览器原生方法 document.title router/index.js router.beforeEach里 //多语言项目,根根据自己项目来 import i18n from '@/i18n/

  • Android开发判断一个app应用是否在运行的方法详解

    本文实例讲述了Android开发判断一个app应用是否在运行的方法.分享给大家供大家参考,具体如下: 在一个应用中,或一个Service .Receiver中有时候需要判断一个应用是否正在运行,以便进行一些相关的处理,这个时候我们需要得到一个ActivityManager,这个Manager顾名思意就是管理Activity的,它有一个方法叫getRunningTasks,可以得到当前系统正在运行的Task的列表,代码如下: ActivityManager am = (ActivityManage

  • Windows下用命令行修改IP地址的方法详解(附批处理文件)

    由于我所处的地方要经常在不同的网络之间切换,比如局域网.系统内部网和外网(光是外网我要常常在3个ADSL网之间切换).我之前一直用的方法是在本机上设置多个不同网段的IP,然后切换路由(Route),这样不同的网段通过不同的网关出去,就可以达到同时访问多个网络的目的.但是这样我发现经常可能出现一些问题,所以我决定用最原始的方法来解决,那就是在要使用某一个网段的时候就只用这个网段的IP,这样就需要不停的更换IP地址.当然,在Windows的"网络连接"属性中这样的更改是很麻烦的,不过还好的

  • 解决在Web.config或App.config中添加自定义配置的方法详解

    .Net中的System.Configuration命名空间为我们在web.config或者app.config中自定义配置提供了完美的支持.最近看到一些项目中还在自定义xml文件做程序的配置,所以忍不住写一篇用系统自定义配置的随笔了.如果你已经对自定义配置了如指掌,请忽略这篇文章.言归正传,我们先来看一个最简单的自定义配置 复制代码 代码如下: <?xml version="1.0" encoding="utf-8" ?> <configura

  • MyBatis拦截器动态替换表名的方法详解

    目录 写在前面 一.Mybatis Interceptor 拦截器接口和注解 二.实现思路 三.代码实现 四.运行结果 写在最后 参考资料 写在前面 今天收到一个需求,根据请求方的不同,动态的切换表名(涵盖SELECT,INSERT,UPDATE操作).几张新表和旧表的结构完全一致,但是分开维护.看到需求第一反应是将表名提出来当${tableName}参数,然后AOP拦截判断再替换表名.但是后面看了一下这几张表在很多mapper接口都有使用,其中还有一些复杂的连接查询,提取tableName当参

  • ASP.NET动态设置页面标题的方法详解

    ASP.NET为我们提供了一个控件类:System.Web.UI.HtmlControls.HtmlGenericControl.它可以实现HTML的元素的一个实例,比如在.cs代码中控制aspx中的<td>元素(注意,它不是<ASP:TableCell>).我们知道,页面标题是被包含在<TITLE></TITLE>中的,而<TITLE>也是一个HTML的元素,所以,我们就可以利用System.Web.UI.HtmlControls.HtmlGe

随机推荐