uniapp 实现更换主题皮肤
uniapp 实现更换主题皮肤
·
换肤:通过设置按钮,可以修改项目页面的颜色、背景、边框等
换肤原理:设置一个全局变量记录当前项目使用哪个肤色方案,元素中使用动态绑定class 使用三元判断全局变量是哪个肤色标记,加载对应的css。这个全局变量建议存储到缓存中,整个项目可以通过缓存获取、修改。这里采用是vuex进行的变量管理
vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它是 uni-app 中常用的状态管理工具,可以将应用程序中的各种数据(如用户信息、全局配置等)进行集中管理和维护,从而方便数据的统一调度和管理。
1:安装 Vuex 库
npm install vuex --save
项目需要在根目录指定的命令(cmd命令)
2: 创建 store:在 src 目录下创建一个名为 store 的文件夹,在其中创建一个名为 index.js 的文件,用于定义和导出 vuex 的实例对象
// store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
curThemeType: 'light',
},
mutations: {
setCurThemeType(state, data) {
state.curThemeType = data;
}
},
actions: {
handleActionAgree( context, boo) {
context.commit('setCurThemeType',boo)
},
},
getters: {
themeType(state) {
return state.curThemeType;
}
},
modules: {}
});
3:使用 mixin混合机制,让主题变量themeType,成为全局变量,是的每个组件都能获得拥有 mixin中的方法和属性。在common文件夹下创建mixins.js
import { mapGetters, mapMutations } from 'vuex';
export default {
install(Vue) {
Vue.mixin({
data() {
return {
};
},
methods: {
...mapMutations(['setCurThemeType']),
},
computed: {
...mapGetters(['themeType'])
},
});
}
};
4:main.js里引入 minxin.js
import App from './App'
//-- 实现换肤 引入 Start
import store from './store'
import myMixin from './common/mixins.js';
//--实现换肤 引入 End
// #ifndef VUE3
import Vue from 'vue'
Vue.config.productionTip = false
App.mpType = 'app'
//-- 实现换肤 调用
Vue.use(myMixin);
try {
function isPromise(obj) {
return (
!!obj &&
(typeof obj === "object" || typeof obj === "function") &&
typeof obj.then === "function"
);
}
// 统一 vue2 API Promise 化返回格式与 vue3 保持一致
uni.addInterceptor({
returnValue(res) {
if (!isPromise(res)) {
return res;
}
return new Promise((resolve, reject) => {
res.then((res) => {
if (res[0]) {
reject(res[0]);
} else {
resolve(res[1]);
}
});
});
},
});
} catch (error) { }
//初始化 store
const app = new Vue({
...App,
store,
})
app.$mount()
// #endif
// #ifdef VUE3
import { createSSRApp } from 'vue'
export function createApp() {
const app = createSSRApp(App)
return {
app
}
}
// #endif
5:编写切换肤色页面swpage.vue
切换按钮:
<switch :checked="switchCheck" @change="toggleTheme" />
script
<script>
export default {
data() {
return {
switchCheck: true, //日间模式选中状态
isDark: false, //白天
}
},
onLoad() {
//根据日夜间选中缓存设置 开关状态
const value = uni.getStorageSync('theme');
if (value == 'light') {
this.switchCheck = true;
} else if (value == 'dark') {
this.switchCheck = false;
} else {
this.switchCheck = true;
uni.setStorageSync('theme', "light");
}
this.setCurThemeType(uni.getStorageSync('theme'));
},
methods: {
toggleTheme() {
//将选中的模式存储缓存
const value = uni.getStorageSync('theme');
if (value == 'light') {
uni.setStorageSync('theme', "dark");
} else if (value == 'dark') {
uni.setStorageSync('theme', "light");
} else {
uni.setStorageSync('theme', "light");
}
this.setCurThemeType(uni.getStorageSync('theme'));
//用于动态的改变定义在vuex当中的变量,达到动态换肤的效果
this.$store.dispatch('handleActionAgree', uni.getStorageSync('theme'));
if (uni.getStorageSync('theme') == 'light') {
uni.setTabBarStyle({//修改底部栏颜色
backgroundColor: '#ffffff'
});
} else if (uni.getStorageSync('theme') == 'dark') {
uni.setTabBarStyle({
backgroundColor: '#2B3757'
});
}else{
uni.setTabBarStyle({
backgroundColor: '#ffffff'
});
}
},
}
}
</script>
6:编写测试页面index.vue。 关键点是通过三元判断确定使用哪个css达到换肤效果。根据themeType 是否dark ,不是则采用的content的css,是dark则采用content-dark的css 实现换肤
<template>
<view class="content" :class="themeType === 'dark' ? 'content-dark' : ''">
<image class="logo" src="/static/logo.png"></image>
<view class="text-area">
<text class="title" :class="themeType === 'dark' ? 'title-dark' : ''">{{title}}</text>
</view>
<view class="setup" @click="toSetUp">
设置
</view>
</view>
</template>
<script>
export default {
data() {
return {
title: 'Hello'
}
},
onLoad() {
},
methods: {
toSetUp() {
uni.navigateTo({
url: '/pages/index/swpage'
})
},
}
}
</script>
<style lang="scss" scoped>
page{
height: 100%;
}
.content {
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: #ffffff;
&-dark{
background-color: #8f8f94;
}
}
.logo {
height: 200rpx;
width: 200rpx;
margin-top: 200rpx;
margin-left: auto;
margin-right: auto;
margin-bottom: 50rpx;
}
.text-area {
display: flex;
justify-content: center;
}
.title {
font-size: 36rpx;
color: #8f8f94;
&-dark{
color: red;
}
}
</style>
7:项目启动后应该采用设置的肤色方案,需要在app.vue中进行配置
<script>
//换肤引入
import {
mapMutations
} from 'vuex';
//
export default {
onLaunch: function() {
//项目启动获取缓存中的皮肤
const value = uni.getStorageSync('theme');
if (value == 'light') {
this.$store.dispatch('handleActionAgree', 'light');
uni.setTabBarStyle({
backgroundColor: '#ffffff'
});
} else if (value == 'dark') {
this.$store.dispatch('handleActionAgree', 'dark');
uni.setTabBarStyle({
backgroundColor: '#2B3757'
});
} else {
this.$store.dispatch('handleActionAgree', 'light');
uni.setTabBarStyle({
backgroundColor: '#ffffff'
});
}
},
methods: {}
}
</script>
<style>
/*每个页面公共css */
</style>
更多推荐
已为社区贡献3条内容
所有评论(0)