useCssVar
实现原理是通过修改css变量的值来自定义主题色,可以单独修改某个dom下的css变量而不影响全局css变量的使用,这就使得可定制主题区域变得非常灵活,除此之外,还可以结合ui框架实现定制主题色,例如element-plus等。具体使用方式请查看官网地址
核心代码如下:
1.hooks定义
// useTheme.ts
import { useCssVar } from '@vueuse/core';
import { useLocalCache } from './useLocalCache';
const { setCache } = useLocalCache();
const themes = {
defaultTheme: {
'--sy-primary-bg-color': '#fff',
'--sy-primary-title-color': '#000',
},
customTheme: {
'--sy-primary-bg-color': '#000',
'--sy-primary-title-color': '#fff',
},
};
type Theme = typeof themes;
export type ThemeTypes = keyof Theme;
export type CssVarTypes = keyof Theme['defaultTheme'];
export function useTheme(
el: HTMLElement | Ref<HTMLElement | null | undefined>,
type: Ref<ThemeTypes> = ref('defaultTheme')
) {
const colors: Record<CssVarTypes | string, Ref<any>> = {};
const switchColor = () => {
Object.keys(themes[type.value]).forEach((item) => {
colors[item].value = themes[type.value][item as CssVarTypes];
});
setCache('theme', type.value);
};
onMounted(() => {
Object.keys(themes.defaultTheme).forEach((item) => {
colors[item] = useCssVar(item, el);
});
switchColor();
});
return {
switchColor,
};
}
2.定义css变量(跟useTheme.ts中css变量保持一致)
// styles/theme.scss
:root {
--sy-primary-bg-color: #fff;
--sy-primary-title-color: #000;
}
使用示例:
1.在main.ts中引入theme.scss
import './styles/theme.scss';
2.在.vue文件中使用
<template>
<div class="theme-box fvc my10px" ref="el">
<div class="text">主题测试区域</div>
</div>
<select placeholder="切换主题" v-model="activeTheme" @change="switchTheme">
<option
v-for="theme in themeOptions"
:key="theme.value"
:value="theme.value"
>
{{ theme.label }}
</option>
</select>
</template>
<script setup lang="ts">
import { useLocalCache, useTheme, ThemeTypes } from '@/hooks'
const { getCache } = useLocalCache();
const el = ref<HTMLElement>();
const activeTheme = ref<ThemeTypes>(getCache('theme'));
const { switchTheme } = useTheme(el, activeTheme);
</script>
<style lang="scss" scoped>
.theme-box {
width: 180px;
height: 40px;
color: var(--sy-primary-title-color);
background-color: var(--sy-primary-bg-color);
border: 1px solid #ccc;
}
</style>
// useLocalCache.ts中theme类型定义代码
import { ThemeTypes } from './useTheme';
const defCache= {
theme: 'default' as ThemeTypes,
// ...
};
// getCache、setCache...
代码中用到的useLocalCache
的详细代码可以参考之前的文章1.vueuse-useLocalStorage在项目中的使用,也可查看项目源码github