一、问题背景
1、VUE3+TS+Pinia前端技术栈,编程实现某网站。
2、网站有主题(包括body、吸顶菜单条、底部区域和相关字体图片等)切换的需求。
3、希望主题切换不存在硬编码,后期可以简单增加数据,即可新增或修改主题。
二、CSS属性绑定颜色变量
v-bind不仅可以在模版template中使用,也可以在css中使用。css代码示例:
background-color: v-bind("themeStore.color.bgTopMenu");
三、Pinia中切换主题代码
export const useThemeStore = defineStore('theme', () => {
const theme = ref('咖啡加白糖')
const color = reactive<Color>({
...themeData.filter(v => v.value === '咖啡加白糖')[0].color
})
const changeTheme = (value: string) => {
theme.value = value
themeData.forEach(v => {
if (v.value === value) {
Object.keys(v.color).forEach(key => {
color[key] = v.color[key]
})
}
})
document.body.style.setProperty('--bg-color-body', color.bgBody)
}
return {
theme,
color,
changeTheme
}
})
其中针对body的DOM操作,是在css中定义了全局变量:
:root {
--bg-color-body: white;
}
四、TS中的数据
/**
* 主题数据
*/
const coffeePlusSugar: Color = {
bgTopMenu: 'Maroon',
fontSrName: 'white',
fontSrSlogan: 'white',
fontStatistics: 'white',
bgBody: 'white',
bgFooter: 'AliceBlue',
fontFooterMenu: 'Gray',
fontFooterMenuHover: 'DodgerBlue',
fontFooterMenuActive: 'DodgerBlue',
fontFooter: 'Gray'
}
const loveCarmine: Color = {
bgTopMenu: 'Gainsboro',
fontSrName: 'DimGray',
fontSrSlogan: 'DimGray',
fontStatistics: 'DimGray',
bgBody: '#d4237a',
bgFooter: '#d4237a',
fontFooterMenu: 'white',
fontFooterMenuHover: 'DodgerBlue',
fontFooterMenuActive: 'DodgerBlue',
fontFooter: 'white'
}
const lightSketch: Color = {
bgTopMenu: 'PaleTurquoise',
fontSrName: 'DimGray',
fontSrSlogan: 'DimGray',
fontStatistics: 'DimGray',
bgBody: 'Snow',
bgFooter: 'LightCyan',
fontFooterMenu: 'Gray',
fontFooterMenuHover: 'DodgerBlue',
fontFooterMenuActive: 'DodgerBlue',
fontFooter: 'Gray'
}
export const themeData = [
{
value: '咖啡加白糖',
label: '咖啡加白糖',
color: coffeePlusSugar
},
{
value: '最爱胭脂红',
label: '最爱胭脂红',
color: loveCarmine
},
{
value: '浅浅的素描',
label: '浅浅的素描',
color: lightSketch
}
]
五、几点注意
1、body的背景颜色比较特殊,需要单独使用document.body.style.setProperty()函数来操作,当然,也可以在离App.vue/main.ts最近的那个组件中,用一个div盒子来覆盖body,就不需要这个DOM操作了。
2、Pinia代码无任何硬编码,新增或修改主题,只需在主体数据中进行。
谢谢!但愿能帮到您。#f_office#一个老码农。