uni-app 动态修改主题色

x33g5p2x  于3个月前 转载在 uni-app  
字(10.1k)|赞(0)|评价(0)|浏览(107)

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

起初都是通过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.jsvue 混入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;
}

css-theme

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;
}

css-variate

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)
                }
            }
        })
    }
}

cue-theme

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
            }
        })
        returncolor
    },
    //根据主题 修改系统 导航栏 底部 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)
    }
}

system-theme

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

theme.js

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 = newVuex.Store({
    modules: {
        theme,
        logIn
    }
})

export default store

index.js

main.js中导入
//引入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

插件市场地址: https://ext.dcloud.net.cn/plugin?id=10498

<!--* @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>

页面代码

四.黑夜 白天主题展示

本文来自博客园,作者:虚乄,转载请注明原文链接:https://www.cnblogs.com/lovejielive/p/16981875.html

相关文章