美文网首页vue
vue3 实现主题切换

vue3 实现主题切换

作者: 暴躁程序员 | 来源:发表于2024-09-05 14:54 被阅读0次

一、方式一:自定义主题(常规版)

  1. 在 src/assets/theme.scss 中定义不同主题变量
html[data-theme='default'] {
  --color-page-bg: #fff;
  --color-page-fs: #000;
  --size-page-fs: 20px;
}

html[data-theme='dark'] {
  --color-page-bg: #000;
  --color-page-fs: #fff;
  --size-page-fs: 20px;
}

html[data-theme='red'] {
  --color-page-bg: red;
  --color-page-fs: #fff;
  --size-page-fs: 20px;
}
  1. 在入口 main.js 中注册
import '@/assets/theme.scss'
  1. 在 index.html 中,定义 data-theme 属性和默认主题值 default
<!doctype html>
<html lang="en" data-theme="default">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" href="/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vite App</title>
  </head>

  <body>
    <div id="app"></div>
    <script type="module" src="/src/main.js"></script>
  </body>
</html>
  1. 在 src/App.vue 中,初始化主题
<script setup>
import { RouterView } from 'vue-router'
import { ref } from 'vue'
// 初始化主题
if (localStorage.getItem('current-theme')) {
  const currentTheme = ref(localStorage.getItem('current-theme'))
  document.documentElement.setAttribute('data-theme', currentTheme.value)
}
</script>

<template>
  <RouterView />
</template>
  1. 在 src/views/HomeView.vue 中,实现切换主题
<script setup>
// 切换主题
const fnToggle = (theme) => {
  localStorage.setItem('current-theme', theme)
  document.documentElement.setAttribute('data-theme', theme)
}

const themeOptions = [
  {
    label: '默认主题',
    value: 'default'
  },
  {
    label: '暗黑主题',
    value: 'dark'
  },
  {
    label: '红色主题',
    value: 'red'
  }
]
</script>

<template>
  <div class="wrapper">
    <h1>vue 主题切换</h1>
    <div>hello world</div>
    <button v-for="item in themeOptions" :key="item.label" @click="fnToggle(item.value)">
      {{ item.label }}
    </button>
  </div>
</template>
<style>
.wrapper {
  height: 100vh;
  width: 100vw;
  overflow-y: auto;
  box-sizing: border-box;
  background: var(--color-page-bg);
  color: var(--color-page-fs);
  font-size: var(--size-page-fs);
}
</style>

二、方式二:通过 style.filter 属性实现主题切换

  1. 在 src/App.vue 中实现
<script setup>
import { ref } from 'vue'

// 1、初始化模式、主题
const colorAreaValue = ref(Number(localStorage.getItem('style-filter-color')) || 0)
const isDark = localStorage.getItem('style-filter-dark') === 'true' ? true : false
const darkValue = ref(isDark || false)
if (!darkValue.value) {
  document.documentElement.style.filter = `hue-rotate(${colorAreaValue.value}deg)`
} else {
  document.documentElement.style.filter = `invert(${darkValue.value ? '85' : '0'}%)`
}
// 2、切换主题
const changeTheme = (v) => {
  document.documentElement.style.filter = `hue-rotate(${v}deg)`
  localStorage.setItem('style-filter-color', v)
  localStorage.setItem('style-filter-dark', false)
  darkValue.value = false // 主题变更要切换到普通模式
}
// 3、切换模式
const changeMode = (v) => {
  document.documentElement.style.filter = `invert(${v ? '85' : '0'}%)`
  localStorage.setItem('style-filter-dark', v)
  if (!v) {
    document.documentElement.style.filter = `hue-rotate(${colorAreaValue.value}deg)` // 切换到普通模式、主题要生效
  }
}
// 置灰模式
const changeGrayMode = () => {
  document.documentElement.style.filter = `grayscale(100%)`
}
</script>
<template>
  <div class="slider-demo-block">
    <div style="width: 40px">主题</div>
    <el-slider v-model="colorAreaValue" @input="changeTheme" show-input :max="360" />
  </div>
  <div class="slider-demo-block">
    <div style="width: 40px">模式</div>
    <el-switch
      v-model="darkValue"
      @change="changeMode"
      class="ml-2"
      inline-prompt
      style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949"
      active-text="普通模式"
      inactive-text="暗黑模式"
    />
  </div>
  <div style="margin: 20px 0">
    <el-button type="primary" @click="changeGrayMode">置灰模式</el-button>
  </div>
  <div class="mb-4">
    <el-button>Default</el-button>
    <el-button type="primary">Primary</el-button>
    <el-button type="success">Success</el-button>
    <el-button type="info">Info</el-button>
    <el-button type="warning">Warning</el-button>
    <el-button type="danger">Danger</el-button>
  </div>
</template>

<style lang="scss">
body {
  background: #f9f9f9;
}
.slider-demo-block {
  max-width: 600px;
  display: flex;
  align-items: center;
}
.slider-demo-block .el-slider {
  margin-top: 0;
  margin-left: 12px;
}
</style>
  1. 由于此方式是借助 css 的 filter 过滤属性实现的主题、模式切换,因此:
1. 此方式不需要定义主题文件
2. 此方式是通过 document.documentElement.style.filter 将过滤属性作用于全局
3. 此方式无法操作局部颜色

相关文章

  • Flutter 学习 之 主题设置 ThemeData

    基于ThemeData 实现主题切换 1. 实现可以亮暗主题切换2. 实现可以颜色主题的切换3.当主题为白色的时候...

  • Flutter 多语言&多主题实现

    目录 多语言实现 多主题实现 状态管理 切换多语言 切换多主题 多语言实现 1. AndroidStudio-> ...

  • 换肤

    Android主题切换(Theme)实现日夜间功能

  • Android 深入(二)- 利用ToolBar实现动态主题

    利用ToolBar实现主题切换原理:切换主题时,将颜色值存储到Preference中,同时更新主题样式。再次打开A...

  • VUE实现主题切换

    使用webpack raw 方式导入文件,防止直接渲染,通过动态添加样式到 实现主题样式切换。 Github: h...

  • iOS实现主题切换

    利用通知NSNotificationCenter和NSUserDefaults实现主题切换。1.先上效果图: 3....

  • css实现主题切换

    项目中常遇到主题且切换的需求,网上有很多实现方法,这里主要总结下分别用css和less实现的思路 CSS实现: 第...

  • 使用Sass实现主题切换

    主题切换大概想到以及找到的有以下几种方式: DWZ富客户端框架主题切换功能 实现方式: 将不同主题的样式抽取出来。...

  • VUE项目中Scss实现主题切换

    项目中提到了全局切换主题的需求。在项目开发中切换主题用到主要技术有Scss,Vuex。 一、Scss部分 实现思路...

  • CSS 变量实现主题切换

    1. 默认配色: 2. 粉色主题配色 3. 切换主题的代码:

网友评论

    本文标题:vue3 实现主题切换

    本文链接:https://www.haomeiwen.com/subject/fvzrljtx.html