实现在vue中自定义主题色彩切换

1. 效果

2. 引言

一般某些网站, 以及应用都会有自定义主题颜色切换的功能, 这可以很大程度上面提高用户的应用体验感,通过自定义主题色彩,可以满足大多用户对色彩方面的需求.

比如说:

网易云PC端:

QQ PC端

3. 本次demo介绍

本次demo 我们采用的是vue3 进行展示.

实现的功能:

  • 纯色主题切换
  • 渐变色彩主题切换

4. Demo 搭建

4.1 前期工作

  • 使用vite内置的指令快速搭建基础vue3项目结构
  • 删除不需要的代码以及文件
  • 启动项目

我们采用vite构建工具,使用内置的指令快速搭建vue3 项目.

更多内置模板指令, 可以查看官网cn.vitejs.dev/guide/

shell 复制代码
pnpm create vite my-vue-app --template vue

然后安装项目依赖

shell 复制代码
pnpm install

最后启动项目

shell 复制代码
pnpm run dev

然后我们将app.vue自带的基础代码框架进行删除即可. components 的组件也可以删除, 因为完全用不到.自带的style.css 里面的代码也可以删除, 编写我们自己的.

最后我们打开浏览器应该是这空白的.

4.2 布局和思路分析

先看下效果:

布局页面分析:

  1. 左上角的svg色板 是一个整体,存放于一个大的容器里面
  2. 大容器设置固定定位, position:fixed
  3. svg 图标下面为一个色板. 色板内部分为上下两部分 , 纯色渐变色
  4. 纯色盒子里面是一个个的不同色块盒子

大家看下我手画的图, 有点难看😂

思路分析:

  1. 点击svg皮肤图标, 色板展示. 再次点击色块隐藏, 引入一个变量进行控制
  2. 色块的生成采用v-for循环, 需要准备一个包含纯色的数组, 和 一个包含渐变色的数组
  3. 点击色块,执行改变#app的背景颜色的函数.

4.3 完整代码

直接上代码了:

js 复制代码
<template>

  <div class="container">
    <div class="leftChangeThemeBox">
      <img src="./assets/theme.svg" alt="" id="themeBth" @click="openThemePanel" />

      <div class="themeBox" v-show="IsShowColorBoard">
        <!-- 纯色盒子 -->
        <div class="SolidColorBox">
          <div v-for="(color, index) in colors" :key="index" :style="{ backgroundColor: color }"
            @click="changeBackgroundColor(color)" class="box"></div>
        </div>
        <!-- 渐变盒子 -->
        <div class="GradientColorBox">
          <div v-for="(color, index) in gradients" :key="index" :style="{ background: color }"
            @click="changeBackgroundColor(color)" class="box"></div>
        </div>
      </div>
    </div>
    <h2>Hello Vue</h2>
  </div>

  <!-- 纯色盒子 -->
</template>

<script setup>
import { ref } from "vue";

// 用来决定色彩主题面板是否显示, 默认不显示
const IsShowColorBoard = ref(false);

// 纯色
const colors = [
  "#ffffff",
  "rgb(255,92,138)",
  "rgb(113,127,249)",
  "rgb(255,143,87)",
  "rgb(255,215,0)",
  "#FFDAFE",
  "#82FFB6",
  "#4C9CA9",
  "#D3B9FF",
  "#fb4b00",
  "#00d8dd",
  "#C9D6FF",
];

// 渐变色
const gradients = [
  "linear-gradient(120deg, #84fab0 0%, #8fd3f4 100%)",
  "linear-gradient(225deg, #77a1d3, #79cbca, #e684ae)",
  "linear-gradient(225deg, #bdc3c7, #2c3e50)",
  "linear-gradient(225deg, #59c173, #a17fe0, #5d26c1)",
  "linear-gradient(225deg, #ff758c, #ff7eb3, #ff758c)",
  "linear-gradient(128deg, #a9ffe9 0%, #406fdd 100%)",
  "linear-gradient(19deg, #FAACA8 0%, #DDD6F3 100%)",
  "linear-gradient(225deg, #D9AFD9 0%, #97D9E1 100%)",
  "linear-gradient(135deg, #62bbf1 0%, #cbccdf 100%)",
  "linear-gradient(225deg, #FBAB7E 0%, #a6f38e 100%)",
  "linear-gradient(90deg, #114357, #f29492)",
  " linear-gradient(to left, #fc354c, #0abfbc)",
];

//打开 主题面板
const openThemePanel = () => {
  IsShowColorBoard.value = !IsShowColorBoard.value
}
const changeBackgroundColor = async (color) => {
  // 拿到元素
  const el = document.getElementById("app");
  // 将main的背景颜色设置为点击的颜色
  el.style.background = color;
};

// 内置6个渐变主题
</script>

<style scoped>
.container {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.leftChangeThemeBox {
  position: fixed;
  left: 10px;
  top: 10px;
  width: 300px;
  height: auto;
}

.themeBox {
  width: 100%;
  height: auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
  border: 1px solid #ccc;
  background-color: rgb(132, 132, 132);
}

.GradientColorBox,
.SolidColorBox {
  display: flex;
  flex-wrap: wrap;
  width: 100%;
  height: 100px;
  margin-bottom: 25px;
  cursor: pointer;
}

.GradientColorBox {
  margin-bottom: 0px;
}

.box {
  width: 30px;
  height: 30px;
  margin: 5px;
}

#themeBth {
  width: 30px;
  height: 30px;
  cursor: pointer;
}
</style>

对了 , 在style.css文件里面需要添加一下关于 #app 的样式, 设置一下过渡, 这样色彩切换有动画效果, 更丝滑一点.

css 复制代码
*{
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

#app{
  width: 100vw;
  height: 100vh;
  overflow: hidden;
  transition: all 0.5s ease-in-out; 
}

5. 额外扩展

当在实际项目中, 比如说你希望用户这次设置好了主题色彩,然后下次登录的时候依旧保持上次设置的主题色彩.

你可以采用下面的这种方案

  • 首先数据库对于用户表添加了bgColor 字段, 作为用户自定义颜色的标识
  • 用户登录的时候, 初始化userStore里面的信息, 这个信息主要从后端返回的接口里面拿到.
  • 然后页面背景默认就是userStore里面的值.

针对页面刷新, store信息丢失,可以使用持久化store信息的插件解决 .pinia-persistedstate-plugin

图标

图标素材是从阿里巴巴矢量图标库 网站上搜索的 地址:www.iconfont.cn/

相关推荐
永日45670几秒前
学习日记-HTML-day51-9.9
前端·学习·html
狗头大军之江苏分军17 分钟前
iPhone 17 vs iPhone 17 Pro:到底差在哪?买前别被忽悠了
前端
小林coding17 分钟前
再也不怕面试了!程序员 AI 面试练习神器终于上线了
前端·后端·面试
文心快码BaiduComate29 分钟前
WAVE SUMMIT深度学习开发者大会2025举行 文心大模型X1.1发布
前端·后端·程序员
babytiger30 分钟前
python 通过selenium调用chrome浏览器
前端·chrome
passer98136 分钟前
基于webpack的场景解决
前端·webpack
奶昔不会射手1 小时前
css3之grid布局
前端·css·css3
举个栗子dhy1 小时前
解决在父元素上同时使用 onMouseEnter和 onMouseLeave时导致下拉菜单无法正常展开或者提前收起问题
前端·javascript·react.js