Vue3 + Vite + Css3切换主题

发布时间:2024年01月17日

1、css3中变量的作用

一个系统或者说一个项目中,往往涉及到很多颜色,但是如果系统看起来样式规整统一的话可能在色值方面偏靠一个色系,字体,颜色,背景颜色,图标颜色等等。
所有可以在css中定义统一的变量,就不用到处去改防止在修改的时候遗漏。

2、css3中如何声明变量

/**局部设置*/
div {
--bg-color: red;
}
/**全局设置*/
:root{
  --common-background-color: #FFF;
  --common-font-color: #333333;
}

3、css3中如何使用变量

  background-color: var(--common-background-color);

4、css3中设备备用值

   background-color: var(--common-background-color, #ffffff);

5、定义变量中遇到的问题

	// 这样是不生效的
	-- color: #333333
    box-shadow: 0 4px 12px 10px rgba(var(-- color), 0.08);
    // 改成这样是可以的
    -- shadow-color: rgba(var(-- color), 0.08)
     box-shadow: 0 4px 12px 10px var(--shadow-color);
     
     // 不生效
     --size: '30px';
     // 这样可以的
     --size: 30px;

6、切换主题思路(提供了俩种思路)

在网上一顿查找后找到两条思路,可以参考一下element-ui 或者vant-ui 官网上都有切换主题的,但是都是第一种形式
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  1. 第一种:在根节点或者父节点追加类名,通过动态修改类名来切换主题样式
  2. 第二种:可以通过 document.documentElement.style.setProperty() 动态修改 css3变量中的值
    分析了一下,第二种不可行的原因,你在项目中设置了100个css3变量,然后你切换主题的时候修改100个值?不现实吧,也可能是我对前端的了解还是比较少,所以采用的第一种。

7、样式主题涉及到那几部分内容的切换?

  1. 背景颜色
  2. 字体颜色
  3. 阴影效果
  4. 图标
  5. 引用的第三方样式

8、上代码

  1. 定义一个切换主题的按钮或者组件 ThemeButton.vue
<template>
  <div class="ThemeButton" @click="changeTheme">
    <img src="https://b.yzcdn.cn/vant/light-theme.svg" alt="" v-if="darkOrLight" />
    <img src="https://b.yzcdn.cn/vant/dark-theme.svg" alt="" v-else />
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { useThemeStore } from '@/stores/theme';

const darkOrLight = ref(true);
const themeStore = useThemeStore();
const changeTheme = () => {
  darkOrLight.value = !darkOrLight.value;
  themeStore.changeTheme();
};
</script>

<style scoped lang="less">
.ThemeButton {
  width: 35px;
  height: 35px;
  border-radius: 50%;
  display: flex;
  justify-content: center;
  align-items: center;

  img {
    width: 30px;
    height: 30px;
  }

  background-color: #fff;
}
</style>
  1. 在全局中存储一下当前主题(piana)theme.ts
import { defineStore } from 'pinia';
import { ThemeEnums } from '@/utils/ThemeEnums';

export const useThemeStore = defineStore({
  id: 'theme',
  state: () => ({
    theme: ThemeEnums.LIGHT_THEME
  }),
  actions: {
    changeTheme() {
      this.theme = this.theme === ThemeEnums.LIGHT_THEME ? ThemeEnums.DARK_THEME : ThemeEnums.LIGHT_THEME;
    }
  },
  persist: {
    enabled: true,
    storage: sessionStorage
  } as any
});

  1. 主题的枚举 ThemeEnums.ts
export enum ThemeEnums {
  // 暗黑主题
  DARK_THEME = 'dark',
  // 明亮主题
  LIGHT_THEME = 'light'
}

  1. 在vue的跟组件也就是APP.vue 中添加动态class
<template>
  <div class="App AppClass" v-loading="globalLoading" :class="useThemeStore().theme">
    <router-view v-slot="{ Component, route }">
      <keep-alive :include="cacheList">
        <component :is="Component" />
      </keep-alive>
    </router-view>
    <TabBar class="option_menu" v-if="isShowTabBar" />
  </div>
</template>
  1. 定义俩套主题(dark.less light.less)别忘记在main.css 中把这俩个主题引入一下
:root {
  --light-background-color: #FFFFFF;
  --light-font-color: #333333;
  --light-tab-bar-shadow-color: rgba(#121621, 0.08);
}

.light {
  background-color: var(--light-background-color);

  .home_content_wrapper {
    background-color: var(--light-background-color);

    .menu li span {
      color: var(--light-font-color);
    }
  }

  .tabBarClass .tabBar {
    box-shadow: 0 4px 12px 10px var(--light-tab-bar-shadow-color);
  }

  // 消息列表
  .MessageListClass {
    .list_wrap {
      background-color: var(--light-background-color);

      .list_item {
        background-color: var(--light-background-color);
      }
    }
  }

}

light 其实就是默认原来的样式,黑暗主题涉及的可能更多是颜色的对比后,包括第三方组件的样式重写等


:root {
  --dark-background-color: #242424;
  --dark-font-color: #FFF;
  --dark-tab-bar-shadow-color: rgba(#d5cbcb, 0.08);
  --dark-item-content-shadow-color: rgba(#eeeaea, 0.12);
  --color: #eeeaea;
}

.dark {
  background-color: var(--dark-background-color);

  .home_content_wrapper {
    background-color: var(--dark-background-color);

    .menu li span {
      color: var(--dark-font-color);
    }
  }

  .tabBarClass .tabBar {
    box-shadow: 0 4px 12px 10px var(--dark-tab-bar-shadow-color);
  }

  // vant 样式重置
  .van-cell-group {
    border: none;
  }

  .van-cell {
    background-color: var(--dark-background-color);
    color: var(--dark-font-color);
  }

  .van-field__label {
    color: var(--dark-font-color);
  }

  .van-cell:after {
    border-bottom: none;
  }

  .van-hairline--top-bottom:after {
    border: none;
  }

  .van-tabs__nav {
    background-color: var(--dark-background-color);
  }

  .van-tab {
    color: var(--dark-font-color);
  }

  .van-text-ellipsis {
    color: var(--dark-font-color);
  }

  .van-popup {
    background-color: var(--dark-background-color);
  }

  .van-cascader__title {
    color: var(--dark-font-color);
  }

  .van-cascader__option {
    color: var(--dark-font-color);
  }

  .van-field__control {
    color: var(--dark-font-color);
  }
  .van-checkbox__label{
    color: var(--dark-font-color);
  }

  // 带统计的按钮
  .total_content_wrapper {
    .van-submit-bar__text {
      color: var(--dark-font-color);
    }
  }
  .van-collapse-item__content{
    background-color: var(--dark-background-color);
    border: 1px solid var(--dark-item-content-shadow-color);
    .inspection_content{
      color: var(--dark-font-color) !important;
    }
    .van-radio__label{
      color: var(--dark-font-color) !important;
    }
  }
  .content_wrapper{
    border: 1px solid var(--dark-item-content-shadow-color);
    border-radius: 5px;
  }

  // 列表样式
  .item_content_wrapper {
    border: 1px solid var(--dark-item-content-shadow-color);
    box-shadow: 3px 3px 6px var(--dark-item-content-shadow-color);

    .title_content {
      color: var(--dark-font-color);
    }
  }

  // 消息列表
  .MessageListClass {
    .list_wrap {
      background-color: var(--dark-background-color);

      .list_item {
        background-color: var(--dark-background-color);
        border: 1px solid var(--dark-item-content-shadow-color);
        box-shadow: 3px 3px 6px var(--dark-item-content-shadow-color);
      }
    }
  }

  // 企业首页
  .statistic_content{
    border: 1px solid var(--dark-item-content-shadow-color);
    color: var(--dark-font-color);
    .time_bgc{
      background-color: var(--dark-background-color);
      .time{
        background-color: var(--dark-background-color) !important;
      }
    }
  }
  .van-cell-group {
    .van-cell {
      &:nth-child(odd) {
        background-color: var(--dark-background-color) !important;
      }
      :deep(.van-cell__title) {
        color: var(--dark-font-color) !important;
      }

      .van-cell__value {
        color: var(--dark-font-color) !important;
      }
    }
  }
  .company_name{
    color: var(--dark-font-color);
  }

  .ConfirmCheckBtnClass{
    background-color: var(--dark-background-color) !important;
    border: 1px solid var(--dark-background-color) !important;
    .tip_content{
      color: var(--dark-font-color);
    }
  }
  .LoadingClass{
    background-color: var(--dark-background-color) !important;
  }
}
/*重置样式*/
@import './reset.css';

/*样式初始化*/
@import './base.scss';

/*通用样式*/
@import "./common.css";

/*主题-黑色*/
/*@import "./theme.css";*/
@import "./theme/dark.less";
@import "./theme/light.less";


文章来源:https://blog.csdn.net/Yue_zuozuo/article/details/135623950
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。