Dynamic switching of themes and styles
Dynamic Theme and Style Switching
In uni-app development, dynamically switching themes and styles can significantly enhance user experience. Through flexible configuration, a single codebase can adapt to multiple visual styles, meeting various scenario requirements.
Basic Implementation Solution
CSS variables are the core technology for implementing dynamic themes. Define global variables in uni.scss
:
:root {
--primary-color: #007AFF;
--bg-color: #FFFFFF;
--text-color: #333333;
}
.dark-theme {
--primary-color: #0A84FF;
--bg-color: #1C1C1E;
--text-color: #F2F2F7;
}
Use these variables in components:
<template>
<view class="container">
<text class="title">Dynamic Theme Example</text>
</view>
</template>
<style>
.container {
background-color: var(--bg-color);
}
.title {
color: var(--text-color);
}
</style>
State Management Solution
Managing theme states with Vuex or Pinia is more efficient:
// store/theme.js
export default {
state: {
currentTheme: 'light'
},
mutations: {
switchTheme(state, theme) {
state.currentTheme = theme
}
}
}
Switch themes in pages:
<script>
import { mapState, mapMutations } from 'vuex'
export default {
computed: {
...mapState(['currentTheme'])
},
methods: {
...mapMutations(['switchTheme']),
toggleTheme() {
const newTheme = this.currentTheme === 'light' ? 'dark' : 'light'
this.switchTheme(newTheme)
document.documentElement.className = newTheme + '-theme'
}
}
}
</script>
Dynamic Style Binding
Combine conditional classes and style objects for more flexible style control:
<template>
<button
:class="['btn', themeClass]"
:style="buttonStyle"
@click="handleClick"
>
Toggle Theme
</button>
</template>
<script>
export default {
data() {
return {
isDark: false
}
},
computed: {
themeClass() {
return this.isDark ? 'dark-theme' : 'light-theme'
},
buttonStyle() {
return {
backgroundColor: this.isDark ? '#333' : '#EEE',
color: this.isDark ? '#FFF' : '#000'
}
}
},
methods: {
handleClick() {
this.isDark = !this.isDark
}
}
}
</script>
Multi-Platform Adaptation Solution
Different platforms may require special handling:
// Determine platform
function getPlatformTheme() {
#ifdef H5
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
#endif
#ifdef APP-PLUS
return plus.navigator.getUIStyle() === 'dark' ? 'dark' : 'light'
#endif
return 'light'
}
Theme Persistence
Use local storage to maintain user preferences:
// utils/theme.js
export function saveTheme(theme) {
uni.setStorageSync('selectedTheme', theme)
}
export function loadTheme() {
return uni.getStorageSync('selectedTheme') || 'light'
}
Load on app startup:
// App.vue
export default {
onLaunch() {
const savedTheme = loadTheme()
this.$store.commit('switchTheme', savedTheme)
document.documentElement.className = savedTheme + '-theme'
}
}
Advanced Theme Switching Animation
Add transition effects to enhance experience:
<template>
<view class="theme-transition" :class="currentTheme">
<!-- Page content -->
</view>
</template>
<style>
.theme-transition {
transition: background-color 0.3s ease, color 0.3s ease;
}
</style>
Dynamic Icon Switching
Switch icon resources based on theme:
<template>
<image :src="themeIcon" mode="aspectFit" />
</template>
<script>
export default {
computed: {
themeIcon() {
return this.$store.state.currentTheme === 'dark'
? '/static/icon-dark.png'
: '/static/icon-light.png'
}
}
}
</script>
Theme Configuration System
Create an extensible theme configuration:
// themes.js
export const themes = {
light: {
primary: '#007AFF',
secondary: '#34C759',
danger: '#FF3B30'
},
dark: {
primary: '#0A84FF',
secondary: '#30D158',
danger: '#FF453A'
},
professional: {
primary: '#5856D6',
secondary: '#FF9500',
danger: '#FF2D55'
}
}
Dynamic injection during use:
function applyTheme(themeName) {
const theme = themes[themeName]
for (const [key, value] of Object.entries(theme)) {
document.documentElement.style.setProperty(`--${key}-color`, value)
}
}
Responsive Theme Switching
Listen for system theme changes:
// App.vue
export default {
mounted() {
#ifdef H5
window.matchMedia('(prefers-color-scheme: dark)')
.addEventListener('change', e => {
this.$store.commit('switchTheme', e.matches ? 'dark' : 'light')
})
#endif
}
}
Component Library Theme Adaptation
Handle third-party component library themes:
// Modify uView theme
import uView from 'uview-ui'
Vue.use(uView)
function setUViewTheme(theme) {
uni.$u.config.theme = theme === 'dark' ? {
primary: '#0A84FF',
contentBg: '#1C1C1E'
} : {
primary: '#007AFF',
contentBg: '#FFFFFF'
}
}
Performance Optimization Recommendations
- Reduce unnecessary style recalculations
- Use CSS variables instead of directly modifying class names
- Use
v-if
instead ofv-show
for complex components - Preload theme resources
// Preload dark theme images
uni.preloadImage({
urls: ['/static/dark-bg.jpg', '/static/dark-icon.png']
})
User Experience for Theme Switching
- Add transition animations while maintaining quick response
- Provide theme previews in settings page
- Consider accessibility for color-blind users
- Maintain contrast for important elements
<template>
<view class="theme-preview"
v-for="theme in availableThemes"
:key="theme.name"
:style="{ backgroundColor: theme.colors.background }"
@click="selectTheme(theme.name)">
<text :style="{ color: theme.colors.text }">{{ theme.label }}</text>
</view>
</template>
Enterprise-Level Theme Solutions
Large-scale applications can adopt CSS-in-JS solutions:
// Using CSS-in-JS library
import { createUseStyles } from 'react-jss'
const useStyles = createUseStyles({
container: props => ({
backgroundColor: props.theme.background,
color: props.theme.text
})
})
function MyComponent() {
const theme = useTheme() // Get current theme from context
const classes = useStyles({ theme })
return <view class={classes.container}>Content</view>
}
Testing Strategies for Dynamic Themes
- Automate UI testing under different themes
- Verify color contrast meets WCAG standards
- Test performance impact during theme switching
// Test case example
describe('Theme Switching', () => {
it('should correctly apply dark theme', () => {
store.commit('switchTheme', 'dark')
expect(document.documentElement.className).toContain('dark-theme')
expect(getComputedStyle(document.body).backgroundColor).toBe('rgb(28, 28, 30)')
})
})
Extensibility Design for Theme Systems
- Support custom theme uploads
- Implement theme property inheritance
- Establish theme version control
// Theme merging strategy
function mergeThemes(baseTheme, customTheme) {
return {
...baseTheme,
colors: {
...baseTheme.colors,
...customTheme.colors
},
spacing: customTheme.spacing || baseTheme.spacing
}
}
Accessibility for Theme Switching
Ensure theme switching doesn't compromise accessibility:
<template>
<button
@click="toggleTheme"
aria-label="Toggle theme"
aria-pressed="isDark"
>
{{ isDark ? 'Switch to Light Mode' : 'Switch to Dark Mode' }}
</button>
</template>
Internationalization Integration for Dynamic Themes
Combine with multilingual support for complete localization:
// Theme-related text
const themeMessages = {
en: {
light: 'Light Mode',
dark: 'Dark Mode'
},
zh: {
light: 'Light Mode',
dark: 'Dark Mode'
}
}
Performance Monitoring for Theme Switching
Track theme switching metrics:
// Performance markers
function toggleTheme() {
performance.mark('themeSwitchStart')
// Execute theme switching logic
performance.mark('themeSwitchEnd')
performance.measure('themeSwitch', 'themeSwitchStart', 'themeSwitchEnd')
const duration = performance.getEntriesByName('themeSwitch')[0].duration
if (duration > 100) {
reportSlowThemeSwitch(duration)
}
}
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn