三种方式实现主题切换方案

前端主题切换

有些时候我们在网站上会进行夜间/白天模式的切换。
这里我们介绍一种流行的切换模式 css变量 + 动态类名来进行切换
非常的简单。废话不多说。我们直接上代码。
第1种是通过 类名和变量来实现的
第2种是通过 属性和变量还实现的
最后1种 给body加 filter: invert(1);

设置两种模式的颜色

//白天模式
body {
  --site-config-color-bar: #fff; //
  --site-config-color-text: #555; //
  --site-config-color-border: rgba(0, 0, 0, 0.12); //
  --site-config-color-shadow: #eee; //
  --site-config-color-introduce-border: #2196f3; //
  --site-config-color-primary: #2196f3; //
  --site-config-color-side-bar: #3a7afe; //
  --site-config-color-side-bar-active-background: #3a7afe1a; //
}

//夜间模式
body.dark {
    --site-config-color-bar: #1e1e1e; //
    --site-config-color-text: #fff; //
    --site-config-color-border: #333; //
    --site-config-color-shadow: #121212; //
    --site-config-color-introduce-border: #555;  //
    --site-config-color-primary: #96cbfe; //
    --site-config-color-side-bar: #4a7afe; //
    --site-config-color-side-bar-active-background: #4a7afe1a; //
}

ps:将这两种模式的代码放置在全局中。比如app.vue文件中。
反正要在项目的全局中可以使用就行了。

通过给body设置dark类名和移除类名来显示夜间和白天

<template>
  <div>
    <div class="top-header">
       我是顶部的标题
      <button class="change-btn" @click="changeBgHandler">切换皮肤</button>
    </div>
    <div class="cont-box">
      <div class="left-asider-box">
        <div class="item-cont-css" :class="{activecss:item.id==1}" 
          v-for="(item,index) in leftData" :key="index">
            {{item.name}}
        </div>
      </div>

      <div class="center-cont">
        <h3 class="h3-css">我是标题</h3>
        <div class="top-center-header">
            <p class="p1-cont" v-for="item in 10" :key="item">
              {{ item}}
              组件库使用中文作为默认语言,支持多语言切换,内置支持 <a> 中文</a>,<a>英文</a>。
            </p>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data() { 
    return {
      msg: 'xx',
      leftData: [
        { name: '优秀的功能1', id: 1 },
        { name: '优秀的功能2', id: 2 },
        { name: '优秀的功能3', id: 3 },
        {name:'优秀的功能4', id:4},
        {name:'优秀的功能5', id:5},
        { name: '优秀的功能6', id: 6 },
        { name: '优秀的功能7', id: 7 },
        { name: '优秀的功能8', id: 8 },
        {name:'优秀的功能9', id:9},
        {name:'优秀的功能10', id:10},
        {name:'优秀的功能11', id:11},
        {name:'优秀的功能12', id:12},
        { name: '优秀的功能13', id: 13 },
        {name:'优秀的功能14', id:14},
        { name: '优秀的功能15', id: 15 },
        { name: '优秀的功能16', id: 16 },
        { name: '优秀的功能17', id: 17 },
        {name:'优秀的功能18', id:18},
        { name: '优秀的功能19', id: 19 },
        { name: '优秀的功能20', id: 20 },
        { name: '优秀的功能21', id: 21 },
        { name: '优秀的功能22', id: 22 },
        { name: '优秀的功能23', id: 23 },
        { name: '优秀的功能24', id: 24 },
      ],
    }
  },
  methods: {
    changeBgHandler() {
      if (!document.body.className) {
        document.body.className = "dark"
      } else {
        document.body.className = ""
      }
    }
  }
  
}
</script>

<style lang="scss" scoped>
.top-header{
  height: 46px;
  line-height: 46px;
  text-align: center;
  background: var(--site-config-color-bar);
  border-bottom: 1px solid var(--site-config-color-border);
  color: var(--site-config-color-text);
  position: relative;
  .change-btn {
    position: absolute;
    right: 20px;
    top: 14px;
  }
}

.cont-box {
  display: flex;
  background: var(--site-config-color-bar);
  .left-asider-box {
    width: 240px;
    box-shadow: 0 8px 12px var(--site-config-color-shadow);
    background: var(--site-config-color-bar);
    .item-cont-css {
      cursor: pointer;
      padding-left: 20px;
      height: 40px;
      line-height: 40px;
      color: var(--site-config-color-text);
    }

    .activecss {
      color: var(--site-config-color-side-bar);
      background: var(--site-config-color-side-bar-active-background);
      transition: color .2s;
    }
  }
}

.center-cont{
  padding-left: 20px;
  padding-right: 20px;
  flex:1;
  .h3-css {
    color: var(--site-config-color-text);
    margin-top: 10px;
    margin-bottom: 10px;
  }
  .top-center-header {
    border-radius: 4px;
    background: var(--site-config-color-bar);
    padding: 20px;
    margin-bottom: 30px;
    box-shadow: 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 2px 2px rgba(0, 0, 0, 0.14), 0 1px 5px rgba(0, 0, 0, 0.12);
  }
  .p1-cont {
    height: 20px;
    color: var(--site-config-color-text);
  }
  .p1-cont a {
    color: var(--site-config-color-primary);
  }
}
</style>

这些网站有夜间模式

https://varlet.gitee.io/varlet-ui/#/zh-CN/home

第2种-变量+属性

全局的颜色样式-app.vue中
<style lang="scss">
*{
  padding: 0;
  margin: 0;
}
/* 默认白天主题 */
:root {
  --bg-color: #fff;
  --text-color: #555;
  // 白天的颜色放置在这里
}
/* 夜间模式主题 */
:root[theme='light'] {
  --bg-color: #1e1e1e;
  --text-color: #fff;
  // 页面模式的放置在这里
}
// 设置整个页面的背景色
html,body{
  background-color: var(--bg-color);
}
</style>

在页面中的使用

<template>
  <div>
      <div class="center-cont">
        <h3 class="h3-css">我是标题</h3>
        <div class="top-center-header">
          <p class="p1-cont" v-for="item in 10" :key="item">{{ item}}组件库使用中文作为默认语言,支持多语言切换,内置支持 <a> 中文</a>,<a>英文</a>。</p>
        </div>
      </div>
      <button class="change-btn" @click="changeBgHandler">切换皮肤</button>
  </div>
</template>

<script>
export default {
  methods: {
    changeBgHandler() {
      if (document.documentElement.getAttribute('theme')) {
        document.documentElement.removeAttribute('theme')
      } else {
        document.documentElement.setAttribute('theme', 'light')
      }
    }
  }
  
}
</script>
<style lang="scss" scoped>
.center-cont{
  background: var(--bg-color);
  .h3-css{
    color: var(--text-color);
  }
  .p1-cont{
    color: var(--text-color);
  }
}
</style>

还有没有更加简单的切换模式 --有的

给body加 filter: invert(1);
但是这一种只能够临时解决问题。
posted @ 2022-11-16 22:26  南风晚来晚相识  阅读(322)  评论(0编辑  收藏  举报