uniapp主题切换

近期公司一直在搞uniapp,搞着搞着发现最麻烦的就是没有根元素,导致好多功能在开发中非常麻烦,近期遇到两个:

  1. 由于前期对uniapp考察不是很全面,导致在功能开发1/3以后才发现没有一个公共头,这时发现没法全局收发消息;
  2. 主题前期有人搞,接手的时候发现是通过localstorage做的,感觉有点点low,而且是从后台传过来的,根本没必要,还会越存越多。

这篇先提个解决主题的办法。
网上找了一些解决方案,发现基本的思路都是通过vuex将颜色存起来,然后在每个页面引用后style,个人感觉不点不太优雅。然后,我想能不能像vue那样通过uniapp的uni.createSelectorQuery()找到根元素绑上固定主题。但是,最后发现H5可行,app不行,就要重新再找别的方法了。
我是通过scss来做主题切换的,大家一般都是通过&选择器渲染到最外层,例如:

@mixin bg_color($color){/*通过该函数设置主题颜色,后期方便统一管理;*/
  background-color:$color;
  [data-theme="theme1"] & {
    background-color:$background-color-theme1;
  }
  [data-theme="theme2"] & {
    background-color:$background-color-theme2;
  }
  [data-theme="theme3"] & {
    background-color:$background-color-theme3;
  }
}

但是由于uniapp是没有根元素的,且项目在最开始的时候并没有注意到,app上更是找不到根元素,所以只能想如何在已有class的dom元素上加上能够判断的标识。
说了这么多直接上代码了
scss-mixin.scss:

/*
@mixin 指令允许我们定义一个可以在整个样式表中重复使用的样式。
*/

// 默认主题的变量集合
$default-theme : (
  bg-color: rgb(22, 194, 194),//背景色
  text-color: rgb(22, 194, 194),//字体颜色
);
// 白天主题的变量集合
$day-theme : (
  bg-color: rgb(145, 96, 255),//背景色
  text-color: rgb(145, 96, 255),//字体颜色
);
// 夜晚主题的变量集合
$night-theme : (
  bg-color: rgb(24, 94, 255),//背景色
  text-color: rgb(24, 94, 255),//字体颜色
);
//定义主题对象
$themes: (// key为主题  value为主题的变量集合
  default-theme: $default-theme,
  day-theme: $day-theme,
  night-theme: $night-theme
);
 
 
// 生成主题背景色样式
@mixin base-background(){
    @each $themename , $theme in $themes {
        &.#{$themename} {
            background-color: map-get($map: $theme, $key: bg-color) !important;
        }
    }
}
// 生成主题字体色样式
@mixin text-color(){
    @each $themename , $theme in $themes {
        &.#{$themename} {
            color: map-get($map: $theme, $key: text-color) !important;
        }
    }
}

html:

<view type="primary" @click="login" class="login_btn" :class="[vtheme]">
	<uni-icons type="arrowthinright" size="25" class="login_icon" style="color: #ffffff;" />
</view>

scss:

.login_btn {
	border-radius: 40px 40px 40px 40px;
	height: 50px;
	background-color: #ffb9b8;
	text-align: center;
	@include base-background();
}

js:

defaultTheme() {
	let theme = uni.getStorageSync('padTheme');
	if (theme === '') {				
		uni.setStorageSync('padTheme', 'default');
		theme = 'default'
		vGetTheme(theme)
	}
},

vuex:

const state = {
    theme: 'default-theme'
}

const mutations = {
    GET_THEME(state,theme) {
        // debugger
        state.theme = theme+'-theme'
    },
}

const actions = {
	
}

const getters = {
    theme: state => state.theme
}

export default {
    namespaced: true,
    state,
    mutations,
    actions,
    getters
}

由于这么写肯定是哪个页面要用哪个页面就要引入vuex,所以利用Vue.mixin()方法进行混入,上代码:
mixin代码,可放在static中,static/mixin/themeMixin.js:

import { mapGetters,mapMutations } from 'vuex'
import Vue from 'vue'
export default {
    install(Vue) {
        Vue.mixin({
            computed:{
                ...mapGetters({
                    vtheme: 'theme/theme',
                })
            },
            methods:{
                ...mapMutations({
                    hide:'app/hide',
                    show: 'app/show',
                    vGetTheme:'theme/GET_THEME',
                })
            }
        })
    }
}

main.js

import mixin from '@/static/mixin/themeMixin.js'
Vue.use(mixin)

全文完~~~

你可能感兴趣的:(uniapp,uni-app,前端,移动开发,sass)