近期公司一直在搞uniapp,搞着搞着发现最麻烦的就是没有根元素,导致好多功能在开发中非常麻烦,近期遇到两个:
这篇先提个解决主题的办法。
网上找了一些解决方案,发现基本的思路都是通过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)
全文完~~~