uni-app动态修改主题色的方法详解
作者:虚乄
前言
老是碰到初版制作完成没多久,就整一出说什么要更改整个项目的色彩体系。真的是宝宝心里苦啊!
起初都是通过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动态修改主题色内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!