uni-app使用scss修改皮肤2

2021-12-24 15:39:41

继续接上次的话题,uni-app做皮肤功能。上次我再uni-app使用scss修改皮肤文章中写到用scss做皮肤。但是后面我意识到,用scss做皮肤,必须每次启动才会生效,在项目中,我们不可能因为某个用户修改了皮肤就重新启动一次服务, 所以上次的方法对于开发者可行,但是对于项目实施,是不可取的.既然不可取,那我们另寻他法。 看到网上很多说使用document去设置data-theme属性,我不否定这种方法在h5中确实是生效的,但是在微信小程序中,根本就没有document属性,所以这种方法是不可取的。

说一下我还皮肤的实现方法。对于小程序,换肤无非三个地方: 1. 顶部导航栏的颜色。 2. 主体中的重要信息已经按钮等颜色。 3. tabbar上的字体颜色与图片。

首先如果用户没有登录,那么我们就显示默认皮肤,如果用户登录了,我们就根据用户的设置,显示用户的设置的颜色。 并且我会把用户的皮肤配置放在vuex中(毕竟每一页都需要换颜色)

第一步: 首先在vuex中写功能逻辑

state: {
   themeMode: 'light', //当前颜色模式 light/dark
   themeColor: '#3964f9', //当前主题颜色
},
mutations: {
    setCurThemeColor(state, data) {
        state.themeColor = data
        uni.setStorageSync("themeColor", data);
        // #ifdef H5
        window.document.documentElement.setAttribute('data-color', data);
        // #endif
    },
    setCurThemeMode(state, data) {
        state.themeMode = data
        uni.setStorageSync("themeMode", data);
        // #ifdef H5
        window.document.documentElement.setAttribute('data-theme', data); //做h5箭筒
        // #endif
    },
},
actions: {		
    getTheme(context) {
        request(api.chooseSkin, {}, 'get').then(res => {
            const {
            	config, //用户的颜色配置
            	skinId,
            	isDark, //是否是夜晚模式
            	isAuto //自动切换白天与夜晚模式
            } = res;
            if (isDark == 1) {
            	context.commit('setCurThemeMode', 'dark')
            } else {
            	context.commit('setCurThemeMode', 'light')
            }
            context.commit('setCurThemeColor', config.hex)
            context.commit('setConfigColor', config)
        }).catch(res => {
            uni.showToast({
            	title: res[0]
            });
        });
    },

第二步:在app.vue中做请求,让用户在进入程序的时候,根据缓存去获取皮肤,如果没有用户的登录缓存,那就显示默认的皮肤颜色。 

methods: {
    ...mapActions([
        'getTheme' // 将 `this.increment()` 映射为 `this.$store.dispatch('increment')`
    ]),
    ...mapMutations(['LOGIN_IN', 'LOGIN_OUT', 'setCurThemeMode', 'setCurThemeColor']),
    handleSetTabBar() {
        const themeMode = uni.getStorageSync('themeMode');

        if (themeMode) {
            this.setCurThemeMode(themeMode);            
            if (themeMode === 'dark') {
            	uni.setTabBarStyle({
            		color: '#666',
            		selectedColor: store.state.themeColor,
            		backgroundColor: '#2B3757'
            	});
            } else {
            	uni.setTabBarStyle({
            		color: '#666',
            		selectedColor: store.state.themeColor,
            		backgroundColor: '#fff'
            	});
            }
        } else {
                store.commit('setCurThemeMode', 'light');
                // #ifdef H5
                window.document.documentElement.setAttribute('data-theme', 'light');
                // #endif
            }
        },
		handleSetColor() {
			const themecolor = uni.getStorageSync('themeColor');
			if (themecolor) {
				this.setColor(themecolor);
			} else {
				store.commit('setCurThemeColor', '#3964f9');
				// #ifdef H5
				window.document.documentElement.setAttribute('data-color', '#3964f9');
				// #endif
			}
		}
	},
	onLaunch: function() {
    const loginInfo = uni.getStorageSync('loginInfo');
    if (loginInfo.token) {
        this.LOGIN_IN(loginInfo);
    } else {
        this.LOGIN_OUT();
    }
     //设置tabbar颜色
    this.handleSetTabBar();
      //设置顶部颜色
    this.handleSetColor();
    this.getTheme();
	},

第三步: 我们还是得靠css实现, 定义好主题色

:root[data-color='#3964f9'] {
	--hex: #3964f9;
}
:root[data-color='#C71585'] {
	--hex: #c71585;
}
:root[data-color='#f63e3e'] {
	--hex: #f63e3e;
}
:root[data-color='#f2c659'] {
	--hex: #f2c659;
}

:root[data-theme='light'] {
	--nav: #3964f9;	
}

:root[data-theme='dark'] {
	--nav: #3964f9;	
}

page-meta[data-theme='dark'] {
	--nav: #3964f9;
}

page-meta[data-theme='light'] {
	--nav: #3964f9;
}

最后一步: 在页面是使用

<page-meta :data-theme="themeMode" :data-color="themeColor">
		<view class="content"></view>
</page-meta>

onReady() {
    const themecolor = uni.getStorageSync('themeColor');
    this.setColor(themecolor); //每一页在页面上去设置修改顶部导航栏的颜色, 没法,page.json中写了默认颜色,就只能每一页去修改
},

.btn-main {
	background-color: var(--hex);
	color: $fff;
}

注意: 因为setColor函数每一个页都需要使用,所以我们用mixin抽离出来,并且在main中引入

import themeMixin from '@/common/theme';
Vue.mixin(themeMixin);

setColor(bg, fg) {
    uni.setNavigationBarColor({
    // 字体颜色 仅支持 #ffffff 和 #000000
        frontColor: fg || '#ffffff',
        //     背景颜色值,有效值为十六进制颜色
        backgroundColor: bg || '#3964f9',
        animation: {
        duration: 250, // 动画时间
        timingFunc: 'easeIn' //linear/easeOut/easeInOut
    }
    });
    // 关闭加载条
    uni.hideNavigationBarLoading()
},

到这里就大功告成了,这篇文章是在我做完功能后写的,可能有漏掉一些代码,但是大致的方向在这里了

关于

联系方式 :

mail: hey_cool@163.com ,
QQ:583459700

备案许可证编号:蜀ICP备16005545号-1 © COPYRIGHT 2015-2024 zhmzjl.com | by: KAPO