uni-app動態(tài)修改主題色的方法詳解
前言
老是碰到初版制作完成沒多久,就整一出說什么要更改整個項目的色彩體系。真的是寶寶心里苦啊!
起初都是通過uni項目自帶的uni.scss中定義,在替換頁面上對應(yīng)的css。以便于達(dá)到一次性修改整體布局的樣式。
一.uni.scss 使用方式
在該文件里定義: $名字 :顏色值;
使用時需要在 style 節(jié)點上加上 lang=“scss”
<style lang="scss" scoped> .bg { height: 120px; width: 100%; background-color: $uni-color-primary; } </style>
該方法使用,適合單一顏色修改,一次修改全局統(tǒng)一。
二.暗黑主題
暗黑模式(Dark Mode),也被稱為夜間模式或深色模式,是一種高對比度,或者反色模式的顯示模式。是一種有利于在黑暗環(huán)境下觀看手機的高對比度的模式。uni-app的暗黑模式,是幫助開發(fā)者完成自己應(yīng)用的暗黑模式的一批配置和API。開發(fā)者可以參考本文實現(xiàn)自己應(yīng)用的暗黑模式。
注:HBuilder X 3.6.9+ 支持 目前只支持深色和淺色
具體介紹看官網(wǎng)地址:uniapp.dcloud.net.cn/tutorial/da…
三.自定義主題配置
可自行定義多種主題配色,通過js動態(tài)修改導(dǎo)航欄等色彩。缺點在于,頁面加載緩慢時前期會顯示出原有的色彩。整體上不影響使用。
注:在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 theme
index.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 store
main.js中導(dǎo)入
//引入 storeimport store from 'store/index.js' Vue.prototype.$store = store
3.頁面中使用
class="conter" :style="{'--page-bg':pageBg}"
為該頁面單獨設(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">點擊查看官方文檔</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)文章
JSON.stringify(遞歸)與?JSON.parse(有限狀態(tài)自動機)的實現(xiàn)代碼
這篇文章主要介紹了JSON.stringify(遞歸)與?JSON.parse(有限狀態(tài)自動機)的實現(xiàn),本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-08-08Bootstrap滾動監(jiān)聽(Scrollspy)插件詳解
滾動監(jiān)聽插件是用來根據(jù)滾動條所處在的位置自動更新導(dǎo)航項目, 顯示導(dǎo)航項目高亮顯示。這篇文章主要介紹了Bootstrap滾動監(jiān)聽(Scrollspy)插件的相關(guān)資料,需要的朋友可以參考下2016-04-04javascript 得到文件后綴名的思路及實現(xiàn)
在上傳文件時,常常要對文件的類型即對文件的后綴名進(jìn)行判斷,用javascript可以很容易的做到這一點。用Javascript解析一個帶絕對路徑的文件名并得到后綴名的方法有很多種,這里列出一種,以供參考。2013-07-07JavaScript中Infinity(無窮數(shù))的使用和注意事項
Infinity(無窮大)在 JS 中是一個特殊的數(shù)字,它的特性是它比任何有限的數(shù)字都大,如果不知道 Infinity,我們在一些運算操作遇到時,就會覺得很有意思,下面這篇文章主要給大家介紹了關(guān)于JavaScript中Infinity(無窮數(shù))的使用和注意事項,需要的朋友可以參考下2022-04-04JavaScript中匿名函數(shù)的遞歸調(diào)用
本文主要介紹了JavaScript中匿名函數(shù)的遞歸調(diào)用。具有很好的參考價值,下面跟著小編一起來看下吧2017-01-01