Electron 实现切换暗_亮模式与主题

Electron 实现切换暗_亮模式与主题_第1张图片

文章末尾附上仓库地址!!!!

清单

  • 模板基于 electron-vite-vue vue3 + ts + vite
  • 组件库 element-plus
  • hooks库 vueuse 、useElementPlusTheme

初始化工程

使用 electron-vite 作为模板,方便大家尽快吧项目跑起来

# 创建模板
npm create electron-vite
# 进入目录
cd electron-vite-vue

# 下载依赖,如果有异常的话可以尝试 cnpm 
cnpm i

# 目前这个模板缺少了 esbuild 依赖,所以需要补上
cnpm i esbuild -D 

# 启动项目
npm run dev

出现这个页面,初始化工程部分就结束了

Electron 实现切换暗_亮模式与主题_第2张图片

ElementPlus 引入

cnpm i element-plus

main.ts 全局引入 ElementPlus

修改 src/main.ts

import { createApp } from "vue";
import "./style.css";
import App from "./App.vue";
// ElementPlus 引入
import ElementPlus from "element-plus";
import "element-plus/dist/index.css";

const app = createApp(App);
// ElementPlus 注册
app.use(ElementPlus);
app.mount("#app").$nextTick(() => {
  postMessage({ payload: "removeLoading" }, "*");
});

启动项目如果报以上错误的话,将缺的两个包下载就好了
image.png

cnpm i @vue/shared @vue/reactivity

测试组件引用

修改 src/App.vue 测试一下组件引用, 务必清空src/style.css哈



            



Electron 实现切换暗_亮模式与主题_第3张图片

ElementPlus暗黑模式

官方文档传送门

  • ElementPlus的暗黑模式 切换方式是在 html元素属性上 增删 class=“dark”
  • 暗黑模式需要在man.ts 文件引入
  • 可以通过 useDark | VueUse 切换暗黑模式

引用element-plus暗黑主题样式

修改 src/main.ts

//.......
// 增加暗黑模式样式文件
import 'element-plus/theme-chalk/dark/css-vars.css'
//.......

使用useColorMode

官方文档传送门

具有自动数据持久化的主题模式hooks(深色/浅色/自定义)。

  • 将颜色模式存在本地存储中持久化
  • 颜色模式为相应式属性
cnpm i @vueuse/core

修改 src/App.vue 改造增加模式切换部分



Electron 实现切换暗_亮模式与主题_第4张图片

Electron暗黑主题同步

细心的小伙伴可能发现了,在改变暗黑模式时,顶部的窗口颜色并没有同步,只有在auto模式下才同步。这是因为顶部的窗口是原生窗口,我们只是改变了webpage 也就是我们特指“html” 部分的主题颜色,下面我们就像两部分联动起来。

IPC(进程间通信)

  • ipcMain模块用于从主进程(main process)异步通信到renderer进程。
  • ipcRenderer模块用于从一个renderer进程异步传送到主进程。

这里本章不做过多介绍,可以先简单理解为发布订阅,后续会更新此系列文章。

改造主线程

修改 electron/main/index.ts 增加两个主线程监听,放在文件末尾即可

// 获取APP当前主题模式
ipcMain.handle("dark-mode", () => {
  return nativeTheme.themeSource;
});
// 设置APP主题模式
ipcMain.handle("dark-mode:change", (_, type: "system" | "light" | "dark") => {
  nativeTheme.themeSource = type;
  return nativeTheme.themeSource;
});

改造

修改 src/App.vue 页面挂载时获取APP 的主题,同步到主题中


Electron 实现切换暗_亮模式与主题_第5张图片

主题切换

因为 ElementPlus 的主题可以通过css变量控制,如下面这个图一样。
Electron 实现切换暗_亮模式与主题_第6张图片

useElementPlusTheme

useElementPlusTheme仓库地址

这个hooks没有找到原作者的博客地址以及文档,但是找到了仓库地址。为了代码可控性以及维护性,直接在文件中创建useElementPlusTheme 而不是下载。

增加文件 src/hooks/useElementPlusTheme.ts

import { onBeforeMount } from "vue";

/** 变量前缀 */
const PRE = "--el-color-primary";
const PRE_LIGHT = `${PRE}-light`;
const PRE_DARK = `${PRE}-dark`;
/** 白色 */
const WHITE = "#ffffff";
/** 黑色 */
const BLACK = "#000000";

const html = document.documentElement;

/**
 * 混合颜色
 */
const mix = (color1: string, color2: string, weight: number) => {
  weight = Math.max(Math.min(Number(weight), 1), 0);
  const r1 = parseInt(color1.substring(1, 3), 16);
  const g1 = parseInt(color1.substring(3, 5), 16);
  const b1 = parseInt(color1.substring(5, 7), 16);
  const r2 = parseInt(color2.substring(1, 3), 16);
  const g2 = parseInt(color2.substring(3, 5), 16);
  const b2 = parseInt(color2.substring(5, 7), 16);
  const r = Math.round(r1 * (1 - weight) + r2 * weight);
  const g = Math.round(g1 * (1 - weight) + g2 * weight);
  const b = Math.round(b1 * (1 - weight) + b2 * weight);
  const _r = ("0" + (r || 0).toString(16)).slice(-2);
  const _g = ("0" + (g || 0).toString(16)).slice(-2);
  const _b = ("0" + (b || 0).toString(16)).slice(-2);
  return "#" + _r + _g + _b;
};

/**
 * 更换颜色的方法
 * @param color 颜色
 */
const changeTheme = (color?: string) => {
  if (!color) return;
  // 设置主要颜色
  html.style.setProperty(PRE, color);
  // 循环设置次级颜色
  for (let i = 1; i < 10; i += 1) {
    html.style.setProperty(`${PRE_LIGHT}-${i}`, mix(color, WHITE, i * 0.1));
  }
  // 设置主要暗色
  const dark = mix(color, BLACK, 0.2);
  html.style.setProperty(`${PRE_DARK}-2`, dark);
};

export function useElementPlusTheme(color?: string) {
  onBeforeMount(() => changeTheme(color));
  return {
    changeTheme,
  };
}

使用 useElementPlusTheme

修改 src/App.vue



Electron 实现切换暗_亮模式与主题_第7张图片

GitHub仓库地址

你可能感兴趣的:(electron,electron,vue.js,前端)