vue3 + vite + sass 换肤效果实现思路

简要

一个网站的换肤效果算是一个比较常见的功能,尤其是在后台管理系统中,我们几乎都能看到他的身影,这里给大家提供一个实现思路。

搭建项目

vite+vue3搭建项目这里就不演示了,vite官网里面讲得很清楚。

注:这里使用的css预处理器是sass,使用前要先安装他的依赖:npm i sass

处理文件基础结构

把src 目录下的assets 和components 文件夹删除,新建src/theme/index.scss:

把App.vue里的代码改成:

xml 复制代码
<template>  
    <div></div>  
</template>  
  
<script setup>  
</script>  
  
<style lang="scss" scoped>  
</style>

把src/style.css里的代码改成:

css 复制代码
body {  
    margin: 0;  
    display: flex;  
    place-items: center;  
    min-width: 320px;  
    min-height: 100vh;  
}  
  
  
button {  
    border-radius: 8px;  
    border: 1px solid transparent;  
    padding: 0.6em 1.2em;  
    font-size: 1em;  
    font-weight: 500;  
    font-family: inherit;  
    cursor: pointer;  
    transition: border-color 0.25s;  
    outline: none; //消除默认点击蓝色边框效果  
}  
  
  
#app {  
    max-width: 1280px;  
    margin: 0 auto;  
    padding: 2rem;  
    text-align: center;  
}

说明: 这里只是实现一个基础的换肤效果,所以文件结构尽量简单化,因此就不引入路由或者其他的项目基础工具。

主要问题

我们在实现一个换肤效果的时候,最重要的一个问题是如何通知系统要使用哪种主题方案,这个其实很好解决,用 document.documentElement.setAttribute 在html标签上进行标记就行。

修改App.vue代码:

vue 复制代码
<template>  
    <div>  
        <form>  
            主题切换:  
            <input type="radio" name="gender" v-model="type" value="light" checked @change="onChange"/>light  
            <input type="radio" name="gender" v-model="type" value="dark" @change="onChange" />dark  
        </form>  
    </div>  
</template>  
  
<script setup>  
    import {ref} from "vue";  
  
    const type = ref('light')  
  
    function onChange(e) {  
        document.documentElement.setAttribute('theme-mode', type.value)  
    }  
</script>  
  
<style lang="scss" scoped>  
  
</style>

效果:

很简单的一段代码,用单选框模拟主题切换。当选中不同的主题时,在浏览器控制台Elements里你就会看到,html标签自动添加了一段theme-mode=dark

效果:

里面theme-mode 和theme-mode里的值都是可以自定义的。

这里就是通过这样区分不同的主题配色方案的。

抽离css变量

在src/theme/index.scss里抽离css变量

代码:

css 复制代码
:root,  
:root[theme-mode='light'] {
    --bg-color: #0052d9;
}

:root[theme-mode='dark'] {
    --bg-color: #2c2c2c;
}

这里有两种主题的配色方案light 和dark,实际项目中可以把他抽离到不同的文件下,这里只是提供一个思路,代码比较简单就不做抽离处理。

在src/main.js里引入:

javascript 复制代码
import { createApp } from 'vue'  
import './style.css'  
import './theme/index.scss'  
import App from './App.vue'

使用主题

到这里就可以使用这些抽离出来的css变量了,这里拿一个按钮举例:

xml 复制代码
<template>  
    <div>  
        <button class="btn">按钮</button>  
        <form>  
            主题切换:  
            <input type="radio" name="gender" v-model="type" value="light" checked @change="onChange"/>light  
            <input type="radio" name="gender" v-model="type" value="dark" @change="onChange"/>dark  
        </form>  
    </div>  
</template>  
  
<script setup>  
    import {ref} from "vue";  
  
    const type = ref('light')  
  
    function onChange(e) {  
        document.documentElement.setAttribute('theme-mode', type.value)  
    }  
</script>  
  
<style lang="scss" scoped>  
    .btn {  
        background-color: var(--bg-color);  
        color: #fff;  
    }  
</style>

按钮的样式 background-color: var(--bg-color); 里的 --bg-color 就是上面抽离出来的css变量,效果如下:

相关推荐
逐光者9333 小时前
STM32——SPI 屏 · Flash · 高速
java·前端·stm32
To_OC3 小时前
同样是让 AI 写全栈,为什么别人一句话就够了
前端·前端框架·next.js
CDwenhuohuo4 小时前
electron pc项目打包成桌面端
前端·javascript·electron
前端大斗师4 小时前
「大于 1000」把 1000 元那单也算进去了:我在 Vue3 订单页对了 10 句话
前端·人工智能·typescript·大模型·原力计划
Jmyd01234 小时前
用 Web VR 引擎搭建 3D 虚拟展厅:从素材上云到多端实时渲染的完整数据链路
前端·3d·vr·三维数字化
刘天远5 小时前
Agent成本核算实现:事件表、状态分布与Python归集
前端·数据库·人工智能·python
欣欣之王来了5 小时前
开发环境准备:Node.js、npm、VS Code安装配置
前端·学习·架构·项目·vue3教程
xiaolinudao1235 小时前
将多个 Excel 表格中的数据合并到单个表中|6 种实现方案全解析
java·前端·excel
计算机毕设定制辅导-无忧学长6 小时前
《校园食堂在线订餐小程序的设计与实现》
java·vue.js·spring boot·微信小程序·uniapp·校园食堂在线订餐小程序
LRL_6 小时前
跨平台 Node 模块安装指南:如何利用 pnpm/npm 配置`supportedArchitectures` 锁定平台依赖
前端·npm·node.js