uni-app動態(tài)修改主題色的方法詳解
前言
老是碰到初版制作完成沒多久,就整一出說什么要更改整個項(xiàng)目的色彩體系。真的是寶寶心里苦啊!
起初都是通過uni項(xiàng)目自帶的uni.scss中定義,在替換頁面上對應(yīng)的css。以便于達(dá)到一次性修改整體布局的樣式。
一.uni.scss 使用方式
在該文件里定義: $名字 :顏色值;

使用時需要在 style 節(jié)點(diǎn)上加上 lang=“scss”
<style lang="scss" scoped>
.bg {
height: 120px;
width: 100%;
background-color: $uni-color-primary;
}
</style>該方法使用,適合單一顏色修改,一次修改全局統(tǒng)一。
二.暗黑主題
暗黑模式(Dark Mode),也被稱為夜間模式或深色模式,是一種高對比度,或者反色模式的顯示模式。是一種有利于在黑暗環(huán)境下觀看手機(jī)的高對比度的模式。uni-app的暗黑模式,是幫助開發(fā)者完成自己應(yīng)用的暗黑模式的一批配置和API。開發(fā)者可以參考本文實(shí)現(xiàn)自己應(yīng)用的暗黑模式。
注:HBuilder X 3.6.9+ 支持 目前只支持深色和淺色
具體介紹看官網(wǎng)地址:uniapp.dcloud.net.cn/tutorial/da…
三.自定義主題配置
可自行定義多種主題配色,通過js動態(tài)修改導(dǎo)航欄等色彩。缺點(diǎn)在于,頁面加載緩慢時前期會顯示出原有的色彩。整體上不影響使用。
注:在APP 微信小程序 H5 都行

1.在根目錄下新建 theme 文件夾
css-theme.scss 主題適配主要css
css-variate.scss 統(tǒng)一顏色值配置
cue-theme.js vue 混入js
system-theme.js 自定義的相關(guān)配置

css-theme
主要為使用sass切換主題,百度一下大部分都是按照以下配置,這里不過多介紹
注:uni中使用時 建議這個scss 在 uni.scss 中 引入該scss
/*
* @author: Jay
* @description: 通過監(jiān)聽 css 變量切換主題色
* @createTime: 2022-12-13 11:29:00
* @introduce: 需要在 uni.scss 中 引入該scss
*/
//統(tǒng)一配置色彩
@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中引入
/* 主題相關(guān)顏色 */ @import './theme/css-theme.scss';
css-variate
主要為配置主題所需css 顏色值,方便統(tǒng)一修改。
/*
主題 統(tǒng)一配置色彩
*/
//頁面背景色
$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 導(dǎo)出
APP 無法使用
h5 微信小程序有值
*/
:export {
dayBg: $day-bg;
nightBg: $night-bg;
jadeBg: $jade-bg;
}cue-theme
主要使用 混入 (mixin) ,方便與在頁面中復(fù)用相同的功能。
該方法主要調(diào)用vuex的數(shù)據(jù) 和 system-theme 中的方法
注:需要在main.js 導(dǎo)入該js
/*
* @author: Jay
* @description: 監(jiān)聽主題變化
* @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() {
//修改導(dǎo)航欄 底部 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)
}
// 監(jiān)聽主題狀態(tài)變化
uni.onThemeChange((res) => {
// console.log("監(jiān)聽主題狀態(tài)變化", 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 主題參數(shù)
...mapGetters({
cueTheme: 'theme/theme',
pageBg: 'theme/pageColor',
}),
},
methods: {
// 修改主題
...mapMutations({
cueGetTheme: 'theme/GET_THEME',
themeCache: 'theme/SET_THEME_CACHE',
pageColorCache: 'theme/SET_PAGE_COLOR'
}),
// 設(shè)置 全局背景色
getSystemBg() {
//從 主題列表 獲取 頁面顏色
let bgColor = system.systemThemeBg(this.cueTheme)
// console.log(bgColor);
//緩存 已設(shè)置 背景色
this.pageColorCache(bgColor)
}
}
})
}
}main.js 導(dǎo)入
//監(jiān)聽主題變化 import theme from './theme/cue-theme.js' Vue.use(theme)
system-theme
主要用來放置一些需要重復(fù)使用的js。可根據(jù)需求自行添加
注: themeList 為系統(tǒng)主題列表參數(shù)相關(guān)配置,用于全局設(shè)置系統(tǒng)導(dǎo)航欄,底部tab顏色值的存放。
注:其中導(dǎo)入 css-variate.scss 在app 沒有相關(guān)數(shù)據(jù)返回,h5,微信小程序則有數(shù)據(jù)返回。其他平臺自行測試。
/*
* @author: Jay
* @description: 主題相關(guān)配置
* @createTime: 2022-12-12 17:45:09
*/
/*
variables APP 拿不到值
h5 微信小程序有值返回
*/
import variables from './css-variate.scss'
export default {
/*
系統(tǒng)主題列表
*/
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: "",
}]
},
//根據(jù)主題 返回背景色
systemThemeBg(name) {
let color = ''
this.themeList().map((item, index) => {
if (item.name === name) {
color = item.navBgApp
}
})
return color
},
//根據(jù)主題 修改系統(tǒng) 導(dǎo)航欄 底部 tab
setSystemTheme(name) {
this.themeList().map((item, index) => {
if (item.name === name) {
// 設(shè)置頁面導(dǎo)航條顏色
this.setNavigationColor(item.name, item.navBgApp)
// 設(shè)置 tabBar 樣式
this.setTabBarColor(item.tabBg, item.tabSeleText, item.tabText)
}
})
},
/*
設(shè)置頁面導(dǎo)航條顏色
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)
},
/*
動態(tài) 設(shè)置 tabBar 樣式
*/
setTabBarColor(bgColor, seleColor, color) {
let tabBar = {
// 背景色
backgroundColor: bgColor || '#ffffff',
// 文字選中時的顏色
selectedColor: seleColor || '#3cc51f',
// 文字默認(rèn)顏色
color: color || '#7A7E83',
}
uni.setTabBarStyle(tabBar)
}
}2.vuex 配置
使用vuex模塊化開發(fā)(module)用于區(qū)分主題相關(guān)設(shè)置 與其他需求。
theme.js 模塊
注:namespaced: true 主要為 cue-theme 用于模塊化調(diào)用。缺少這個,在調(diào)用cue-theme中的方法時,拿不到所需參數(shù)
//主題相關(guān)配置
import system from '../../theme/system-theme'
const theme = {
namespaced: true,
state: {
theme: "day-theme",
//主題列表
theme: system.themeList(),
//頁面背景色
pageColor: "",
},
mutations: {
//設(shè)置主題色
GET_THEME(state, provider) {
state.theme = provider
//修改導(dǎo)航欄 底部 tab
system.setSystemTheme(state.theme)
},
//設(shè)置主題緩存
SET_THEME_CACHE(state, provider) {
uni.setStorage({
key: 'themeType',
data: provider
});
},
//設(shè)置主題緩存
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 themeindex.js 全局導(dǎo)出
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 storemain.js中導(dǎo)入
//引入 storeimport store from 'store/index.js' Vue.prototype.$store = store
3.頁面中使用
class="conter" :style="{'--page-bg':pageBg}" 為該頁面單獨(dú)設(shè)置背景色 ,需要配合 page 設(shè)置頁面高度使用
:data-theme="cueTheme" 給view設(shè)置data-theme屬性,根據(jù)名字匹配對應(yīng)顏色
:class="[cueTheme]" 設(shè)置對應(yīng)的名字, css 中使用 @include text-color();
案例地址: gitee.com/jielov/uni-…
<!--
* @author: Jay
* @description: 動態(tài)修改主題色
* @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">點(diǎn)擊查看官方文檔</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">
當(dāng)前主題:{{cueTheme}}
</view>
<view class="margin-tb-sm text-lg text-center">
當(dāng)前頁面背景色:{{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("當(dāng)前主題:", this.cueTheme);
},
onShow() {},
methods: {
cssEditThemeBut(e) {
//修改主題
this.cueGetTheme(e)
//設(shè)置主題緩存
this.themeCache(e)
//設(shè)置 全局背景色
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>四.黑夜 白天主題展示


總結(jié)
到此這篇關(guān)于uni-app動態(tài)修改主題色的文章就介紹到這了,更多相關(guān)uni-app動態(tài)修改主題色內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript實(shí)現(xiàn)簡單的倒計(jì)時效果
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)簡單的倒計(jì)時效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-06-06
JSON.stringify(遞歸)與?JSON.parse(有限狀態(tài)自動機(jī))的實(shí)現(xiàn)代碼
這篇文章主要介紹了JSON.stringify(遞歸)與?JSON.parse(有限狀態(tài)自動機(jī))的實(shí)現(xiàn),本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-08-08
Bootstrap滾動監(jiān)聽(Scrollspy)插件詳解
滾動監(jiān)聽插件是用來根據(jù)滾動條所處在的位置自動更新導(dǎo)航項(xiàng)目, 顯示導(dǎo)航項(xiàng)目高亮顯示。這篇文章主要介紹了Bootstrap滾動監(jiān)聽(Scrollspy)插件的相關(guān)資料,需要的朋友可以參考下2016-04-04
javascript 得到文件后綴名的思路及實(shí)現(xiàn)
在上傳文件時,常常要對文件的類型即對文件的后綴名進(jìn)行判斷,用javascript可以很容易的做到這一點(diǎn)。用Javascript解析一個帶絕對路徑的文件名并得到后綴名的方法有很多種,這里列出一種,以供參考。2013-07-07
JavaScript中Infinity(無窮數(shù))的使用和注意事項(xiàng)
Infinity(無窮大)在 JS 中是一個特殊的數(shù)字,它的特性是它比任何有限的數(shù)字都大,如果不知道 Infinity,我們在一些運(yùn)算操作遇到時,就會覺得很有意思,下面這篇文章主要給大家介紹了關(guān)于JavaScript中Infinity(無窮數(shù))的使用和注意事項(xiàng),需要的朋友可以參考下2022-04-04
JavaScript中匿名函數(shù)的遞歸調(diào)用
本文主要介紹了JavaScript中匿名函數(shù)的遞歸調(diào)用。具有很好的參考價值,下面跟著小編一起來看下吧2017-01-01

