老是碰到初版製作完成沒多久,就整一出說什麼要更改整個專案的色彩體系。真的是寶寶心裡苦啊!
起初都是透過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+ 支援 目前只支援深色和淺色
具體介紹看官網地址:https://uniapp.dcloud.net.cn/tutorial/darkmode.html
三.自定義主題配置
可自行定義多種主題配色,透過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; }
/* 主題相關顏色 */ @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) } } }) } }
//監聽主題變化 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
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
//引入store import 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();
案例地址: https://gitee.com/jielov/uni-app-tabbar
<!-- * @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>
四.黑夜 白天主題展示