主题效果
::: block-1 在VueUse官网中有这样一个效果,就是点击切换按钮,切换页面主题,由白天切换到黑夜。 :::
今天呢我们封装一个简易前端主题Hook,主要分享其中的实现原理。
封装Hooks
准备两个主题样式
js
export default {
fontSize: '20px',
Color: '#f90',
backgroundColor: '#eee'
}
themeday.js
js
export default {
fontSize: '20px',
Color: '#fff',
backgroundColor: '#333',
}
themedark.js
新建一个hook文件夹,在hook文件夹中新建theme.ts
ts
import { ref, type Ref } from 'vue';
// 定义你的主题类型
interface ThemeType {
fontSize?: string;
Color?: string;
backgroundColor?: string;
}
// 定义你的响应式引用类型
type ThemedRef = Ref<ThemeType | undefined>;
// 导入你的主题对象
import themeday from '../utils/themeday.js';
import themedark from '../utils/themedark.js';
// 初始化你的响应式引用
let Theme: ThemedRef = ref(themeday as ThemeType);
export function useTheme() {
let Localtheme = localStorage.getItem('theme');
Theme.value = Localtheme ? JSON.parse(Localtheme) : themeday;
const changeday = () => {
Theme.value = themeday;
localStorage.setItem('theme', JSON.stringify(themeday));
};
const changedark = () => {
Theme.value = themedark;
localStorage.setItem('theme', JSON.stringify(themedark));
};
// 为返回的对象添加类型注释
return { Theme, changeday, changedark } as { Theme: ThemedRef; changeday: () => void; changedark: () => void };
}
因为页面会刷新,所以使用localstorage把主题存入,这样切换主题后,即使页面刷新主题也不会再改变。
组件中使用
在组件中引入useTheme
html
<template>
<div>123123123</div>
<button @click="changeday" style="width: 100px; height: 50px;margin-top: 100px;">明亮模式</button>
<button @click="changedark" style="width: 100px; height: 50px;">黑暗模式</button>
</template>
<script setup lang="ts">
import { useTheme } from '@/hook/theme'
const { Theme, changeday, changedark } = useTheme()
</script>
引入成功之后该怎样修改页面样式呢?别忘了vue内置指令有一个v-bind 可以动态绑定元素,在js中可以使用,css也可以使用。
css
<style scoped lang="scss">
div {
width: 100px;
height: 100px;
border: 1px solid #ccc;
background-color: v-bind("Theme.backgroundColor");
font-size: v-bind("Theme.fontSize");
color: v-bind("Theme.Color");
}
</style>
效果
谢谢观看~