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
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小白菜S

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值