开发原子APP遇到的问题汇总

136 阅读3分钟

app一键换肤功能的实现思路

  • 定义全局需要切换的主题色(使用css变量 -- 开头)
  • 使用pinia对全局主题色进行存储和转接
  • 封装一键换肤组件和函数进行全局使用

第一步 [定义全局需要切换的主题色(使用css变量 -- 开头)]

我这里定义了两套主题色一套用于修改全局的背景和字体颜色,一套用于修改全局导航栏和tabBar

/* 亮色 */
.light {
	--text-color: #333;
	--bg-color: #fff;
}

/* 黑夜 */
.dark {
	--text-color: #fff;
	--bg-color: #272727;
}

/* teal */
.teal {
	--text-color: #fff;
	--bg-color: #008080;
}

/* violet */
.violet {
	--text-color: #fff;
	--bg-color: #9370DB;
}

/* almond */
.almond {
	--text-color: #fff;
	--bg-color: #ED9678;
}

/* chocolate */
.chocolate {
	--text-color: #fff;
	--bg-color: #CB8E85;
}

/* love */
.love {
	--text-color: #fff;
	--bg-color: #FF7875;
}

/* girl */
.girl {
	--text-color: #fff;
	--bg-color: #FFADD2;
}

/* blue */
.blue {
	--text-color: #fff;
	--bg-color: #ADC6FF;
}
export default {
	light: {
		baseColor: "#fff",
		navigationBarStyle: {
			frontColor: "#333",
			backgroundColor: "#fff",
			animation: {
				duration: 0,
				timingFunc: "easeIn",
			},
		},
		tabBarStyle: {
			backgroundColor: "#fff",
			borderStyle: "#151b29",
		},
	},
	dark: {
		baseColor: "#333",
		navigationBarStyle: {
			frontColor: "#fff",
			backgroundColor: "#333",
			animation: {
				duration: 0,
				timingFunc: "easeIn",
			},
		},
		tabBarStyle: {
			backgroundColor: "#333",
			borderStyle: "#f2f2f2",
		},
	},
	teal: {
		baseColor: "#008080",
		navigationBarStyle: {
			frontColor: "#fff",
			backgroundColor: "#008080",
			animation: {
				duration: 0,
				timingFunc: "easeIn",
			},
		},
		tabBarStyle: {
			backgroundColor: "#008080",
			borderStyle: "#008181",
		},
	},
	violet: {
		baseColor: "#9370DB",
		navigationBarStyle: {
			frontColor: "#fff",
			backgroundColor: "#9370DB",
			animation: {
				duration: 0,
				timingFunc: "easeIn",
			},
		},
		tabBarStyle: {
			backgroundColor: "#9370DB",
			borderStyle: "#008181",
		},
	},
	almond: {
		baseColor: "#ED9678",
		navigationBarStyle: {
			frontColor: "#fff",
			backgroundColor: "#ED9678",
			animation: {
				duration: 0,
				timingFunc: "easeIn",
			},
		},
		tabBarStyle: {
			backgroundColor: "#ED9678",
			borderStyle: "#008181",
		},
	},
	chocolate: {
		baseColor: "#CB8E85",
		navigationBarStyle: {
			frontColor: "#fff",
			backgroundColor: "#CB8E85",
			animation: {
				duration: 0,
				timingFunc: "easeIn",
			},
		},
		tabBarStyle: {
			backgroundColor: "#CB8E85",
			borderStyle: "#008181",
		},
	},
	love: {
		baseColor: "#FF7875",
		navigationBarStyle: {
			frontColor: "#fff",
			backgroundColor: "#FF7875",
			animation: {
				duration: 0,
				timingFunc: "easeIn",
			},
		},
		tabBarStyle: {
			backgroundColor: "#FF7875",
			borderStyle: "#008181",
		},
	},
	girl: {
		baseColor: "#FFADD2",
		navigationBarStyle: {
			frontColor: "#fff",
			backgroundColor: "#FFADD2",
			animation: {
				duration: 0,
				timingFunc: "easeIn",
			},
		},
		tabBarStyle: {
			backgroundColor: "#FFADD2",
			borderStyle: "#008181",
		},
	},
	blue: {
		baseColor: "#ADC6FF",
		navigationBarStyle: {
			frontColor: "#fff",
			backgroundColor: "#ADC6FF",
			animation: {
				duration: 0,
				timingFunc: "easeIn",
			},
		},
		tabBarStyle: {
			backgroundColor: "#ADC6FF",
			borderStyle: "#008181",
		},
	},
};

第二步 [使用pinia对全局主题色进行存储和转接]

import { defineStore } from "pinia";
import systemTheme from '@/utils/systemTheme'


export const useTheme = defineStore({
	id: "theme",
	state: () => ({
		themeType: uni.getStorageSync('theme') ?? '',
		systemTheme: systemTheme
	}),

	getters: {
		getThemeType() : any {
			console.log(this.themeType);
			return this.themeType;
		},
	},
	actions: {
		setTheme(e : string) {
			// 存储到本地
			uni.setStorageSync('theme', e);
			this.themeType = e
			plus.runtime.restart();
		}
	},
});

export const theme = () => {
	const theme = useTheme()
	return theme.themeType
}

第三步 [封装一键换肤组件]

<script lang="ts" setup>
	import { theme, useTheme as themetype } from "@/store/module/theme";
	import systemTheme from "@/utils/systemTheme";
	import { onMounted, ref } from "vue";
	interface ThemeItem {
		k : string;
		name : string;
		color : string;
		switchChecked : boolean
	}
   
	const themeList = ref<ThemeItem[]>([]);

	const systemMsg = ref(false)

	const event = ref()


	const handleSwitch = (i) => {
		themeList.value.forEach(item => {
			item.switchChecked = item.k === i.k ? true : false

		})
		systemMsg.value = true
		event.value = i.k

	}

	const handleConfirm = (e) => {
		useTheme.setTheme(e)
		systemMsg.value = false
	}

	const handleCancel = () => {
		themeList.value.forEach(item => {
			item.switchChecked = uni.getStorageSync('theme') == item.k ? true : false
		})
		systemMsg.value = false
	}

	onMounted(() => {
		const type = {
			light: '精灵白',
			dark: '恶魔黑',
			teal: '孔雀绿',
			violet: '紫罗兰',
			almond: '杏仁饼',
			chocolate: '巧克力',
			love: '薄暮',
			girl: '少女',
			blue: '拂晓蓝'
		}
		for (const k in systemTheme) {
			themeList.value.push({
				k,
				name: type[k],
				color: systemTheme[k]["baseColor"],
				switchChecked: uni.getStorageSync('theme') == k ? true : false
			});
		}
	});
</script>

<template>
	<view :class="theme()" class="w-full ">

		<view v-for="i in themeList" :key="i.name"
			class="w-full h-auto flex justify-between items-center border-b border-[#f2f2f2] px-[20rpx] py-[20rpx]">
			<view class="w-[40rpx] h-[40rpx] rounded-full"
				:style="{backgroundColor: `${i.color}`,border:`${i.color == '#fff' ? '1rpx solid #d9d9d9':'1rpx solid #fff'}`}">

			</view>
			<view class="text-[14px] text-[#222]">
				{{i.name}}
			</view>
			<nut-switch v-model="i.switchChecked" :active-color="i.color=='#fff'?'pink':i.color"
				@click="handleSwitch(i)" />
		</view>
		<u-modal :show="systemMsg" :showCancelButton="true" @cancel="handleCancel" @confirm="handleConfirm(event)"
			confirmText='重启' cancelText="取消" title="系统提示" content='系统主题应用成功,是否重启生效'></u-modal>
	</view>
</template>

第五步 [封装全局修改导航条和tabBar主题的函数]

import systemTheme from '@/utils/systemTheme'


export default function (time : number) {
	const system = uni.getStorageSync('theme')
	setTimeout(() => {
		uni.setNavigationBarColor(systemTheme[system].navigationBarStyle);
		//设置tabbar主题
		uni.setTabBarStyle(systemTheme[system].tabBarStyle)
	}, time)
}

应用

在App.ts使用

<script setup lang="ts">
	import { onLaunch, onShow, onHide } from "@dcloudio/uni-app";
	import modifyNavigationBarStyle from '@/utils/modifyNavigationBarStyle'
	import { onMounted } from "vue";

	onLaunch(() => {

		const naviArr = [
			'navigateTo',
			'redirectTo',
			'reLaunch',
			'switchTab',
			'navigateBack',
		]
		for (let i of naviArr) {
			uni.addInterceptor(i, {
				//监听跳转
				success(e) {
					// 修改导航条
					void modifyNavigationBarStyle(0)
				},
			})
		}
	});

	onShow(() => {

	});
	onHide(() => { });

	onMounted(() => {
		// 修改导航条
		void modifyNavigationBarStyle(200)
	})
</script>


<style lang="scss">
	/* 注意要写在第一行,同时给style标签加入lang="scss"属性 */
	@import "@/uni_modules/uview-plus/index.scss";
	@import "nutui-uniapp/styles/index";
	/* 适配tailwindcss */
	@import url("@/style/tailwindcss.css");
</style>

image.png

效果

image.png

image.png

image.png