Vue3 + Element-plus前端项目-主题切换

简介

现在很多项目都会有一个主题切换,支持客户自定义网站主题。 以下我们通过css变量来完成对一个完整的项目支持主题切换的实践 预览链接 lancejiang.github.io/Lance-Eleme...

1. 配置主题

定义默认主题

ts 复制代码
// settings.ts
export const defaultSettingState = {
    /** 主题模式 */  
    // 主题颜色  
    themeColor: '#409eff',  
    // 暗黑主题  
    isDark: false,
}

配置主题相关的store

ts 复制代码
// modules/settings
// 定义主题配置store
import defaultSettings from 'settings.ts'
import { defineStore } from 'pinia'
export const useSettingStore = defineStore({  
    id: 'setting',  
    state: (): SettingState => defaultSettings,  
    actions: {  
        async changeSetting(...payload: [string, any]) {  
        const [key, value] = payload  
        this[key] = value  
        }  
    }  
})  
  
export default useSettingStore

2. 主题hooks 逻辑

颜色切换工具函数

ts 复制代码
// utils/color.ts
/**  
* @description hex颜色转rgb颜色  
* @param {String} str 颜色值字符串  
* @returns {String} 返回处理后的颜色值  
*/  
export function hexToRgb(str: any) {  
    let hexs: any = ''  
    const reg = /^\#?[0-9A-Fa-f]{6}$/  
    if (!reg.test(str)) return '' 
    str = str.replace('#', '')  
    hexs = str.match(/../g)  
    for (let i = 0; i < 3; i++) hexs[i] = parseInt(hexs[i], 16)  
    return hexs  
}  
  
/**  
* @description rgb颜色转Hex颜色  
* @param {*} r 代表红色  
* @param {*} g 代表绿色  
* @param {*} b 代表蓝色  
* @returns {String} 返回处理后的颜色值  
*/  
export function rgbToHex(r: any, g: any, b: any) {  
    const reg = /^\d{1,3}$/  
    if (!reg.test(r) || !reg.test(g) || !reg.test(b)) return ''
    const hexs = [r.toString(16), g.toString(16), b.toString(16)]  
    for (let i = 0; i < 3; i++) if (hexs[i].length == 1) hexs[i] = `0${hexs[i]}`  
    return `#${hexs.join('')}`  
}

/**  
* @description 加深颜色值  
* @param {String} color 颜色值字符串  
* @param {Number} level 加深的程度,限0-1之间  
* @returns {String} 返回处理后的颜色值  
*/  
export function getDarkColor(color: string, level: number) {  
    const reg = /^\#?[0-9A-Fa-f]{6}$/  
    if (!reg.test(color)) return ''
    const rgb = hexToRgb(color)  
    for (let i = 0; i < 3; i++) rgb[i] = Math.round(20.5 * level + rgb[i] * (1 - level))  
    return rgbToHex(rgb[0], rgb[1], rgb[2])  
}

/**  
* @description 变浅颜色值  
* @param {String} color 颜色值字符串  
* @param {Number} level 加深的程度,限0-1之间  
* @returns {String} 返回处理后的颜色值  
*/  
export function getLightColor(color: string, level: number) {  
    const reg = /^\#?[0-9A-Fa-f]{6}$/  
    if (!reg.test(color)) return ''  
    const rgb = hexToRgb(color)  
    for (let i = 0; i < 3; i++) rgb[i] = Math.round(255 * level + rgb[i] * (1 - level))  
    return rgbToHex(rgb[0], rgb[1], rgb[2])  
}

定义主题hooks useTheme

ts 复制代码
import useSettingStore from './modules/settings'
import { getLightColor, getDarkColor } from './utils/color'
import { storeToRefs } from 'pinia'
export const useTheme = () => {
    const setting = useSettingStore()
    const { themeColor, isDark } = storeToRefs(setting)
    // 暗黑模式切换
    const switchDark = () => {  
        const html = document.documentElement as HTMLElement  
        html.setAttribute('class', isDark.value ? 'dark' : '')  
        changeThemeColor(themeColor.value)
    }
    
    // 修改主题颜色  
    const changeThemeColor = (val: string) => {  
        // 计算主题颜色变化  
        document.documentElement.style.setProperty('--el-color-primary', val)  
        // 颜色加深 :active 触发  
        document.documentElement.style.setProperty('--el-color-primary-dark-2', isDark.value ? `${getLightColor(val, 0.2)}` : `${getDarkColor(val, 0.3)}`)  
        for (let i = 1; i < 10; i++) {  
        const primaryColor = isDark.value ? `${getDarkColor(val, i / 10)}` : `${getLightColor(val, i / 10)}`  
        document.documentElement.style.setProperty(`--el-color-primary-light-${i}`, primaryColor)  
        }  
        setting.changeSetting('themeColor', val)  
    }
    
    // init theme  
    const initTheme = () => {  
        switchDark()
    }
    return {  
        initTheme,  
        switchDark,  
        changeThemeColor
    }
}

3. 项目植入

项目初始化

ts 复制代码
// App.vue script 部分
<script setup lang="ts">  
import { useTheme } from './hooks/useTheme'  
  
// 初始化 主题  
const { initTheme } = useTheme()  
initTheme()
</script>

主题/主题色切换

html 复制代码
<!-- setting.vue template 部分-->
<div>  
    <div class="drawer-title">设置</div>  
    <div class="drawer-wrap">  
        <div class="drawer-item">  
            <span>主题颜色</span>  
            <el-color-picker :model-value="themeColor" @update:model-value="changeThemeColor" />  
        </div>  
        <div class="drawer-item">  
            <span>暗黑主题</span>  
            <el-switch v-model="isDark" inline-prompt active-icon="Sunny" inactive-icon="Moon" @change="switchDark" />  
        </div>  
    </div>  
</div>
ts 复制代码
// setting.vue script 部分
import { storeToRefs } from 'pinia'
<script setup lang="ts">  
    import { storeToRefs } from 'pinia'  
    import { useTheme } from '@/hooks/useTheme'  
    import useSettingStore from './modules/settings'

    const setting = useSettingStore()
    const { switchDark, changeThemeColor } = useTheme()  
    const { isDark, themeColor } = storeToRefs(setting)  
</script>

以上就是项目 完整的 主题切换的功能啦

✿✿ヽ(°▽°)ノ✿

项目可能还含有 水印 布局切换 都可以在 setting.vue 文件中做扩展 完整的项目看下面喔

结束

分享给大家一个Vue3 + Ts + Element-plus & Vite 搭建,开箱即用的后台管理项目, 手机端已兼容,如果觉得不错希望可以得到各位大佬的star

项目链接 github.com/LanceJiang/...
访问链接 lancejiang.github.io/Lance-Eleme...

相关推荐
王小菲1 分钟前
JavaScript 装箱机制与解构赋值深度解析
前端·javascript·面试
用户49430538293803 分钟前
基于GIS数据的即时建筑模型编辑软件
前端·算法·gis
Shawn5907 分钟前
如何使用useCallback优化React性能?
前端·react.js
Suckerbin14 分钟前
PHP前置知识-HTML学习
前端·学习·html
java1234_小锋17 分钟前
一周学会Flask3 Python Web开发-SQLAlchemy查询所有数据操作-班级模块
开发语言·前端·python
OpenTiny社区36 分钟前
OpenTiny技术直播讲师招募:与开源同行,点亮技术影响力!
前端·vue.js·低代码
还是鼠鼠44 分钟前
Node.js--CommonJS 模块化规范详解:使用方法、缓存机制与模块解析
前端·javascript·vscode·缓存·node.js·web
冰夏之夜影1 小时前
【css酷炫效果】纯CSS实现大风车旋转效果
前端·css
customer081 小时前
【开源免费】基于SpringBoot+Vue.JS电商应用系统(JAVA毕业设计)
java·vue.js·spring boot·后端·开源
摇滚侠1 小时前
项目中pnpm版本和全局pnpm版本不一致
vue.js