Skip to main content

主题切换

基于 contextBridge 通讯执行主题切换

  • 主进程:

    在主进程的createWindow方法中,增加两个ipcMain.on监听preload.ts发来的信号

async function createWindow() { 
const win = new BrowserWindow({
... 设置窗口相关
webPreferences: {
nodeIntegration: false,
contextIsolation: true,
preload: path.resolve(path.join(__dirname, '../public/preload.ts')),
},
});

ipcMain.handle('toggle-theme:dark', () => {
nativeTheme.themeSource = 'dark';
});

ipcMain.handle('toggle-theme:light', () => {
nativeTheme.themeSource = 'light';
});
... (其他业务代码)
}
  • preload.ts

    运行contextBridge注册electron API

const { contextBridge, ipcRenderer } = require("electron");
contextBridge.exposeInMainWorld("darkMode", {
toggleDarkTheme: () => ipcRenderer.invoke("toggle-theme:dark"),
toggleLightTheme: () => ipcRenderer.invoke("toggle-theme:light"),
});
  • 样式文件
// 暗主题
@media (prefers-color-scheme: dark) {
body { background: #333; color: white; }
}

// 亮主题
@media (prefers-color-scheme: light) {
body { background: #fff; color: black; }
}
  • renderer.vue
<template lang="pug">
...
//- 设置一个按钮
el-switch(
id="toggle-theme-button"
v-model="openDarkMode"
size="large"
active-text="Open"
inactive-text="Close"
@change="toggleTheme")
...
</template>


<script lang="ts">
...
methods: {
toggleTheme() {
if(this.openDarkMode){
// 如果无法使用window,可以尝试 (window as any)
window.darkMode.toggleDarkTheme()
}else{
window.darkMode.toggleLightTheme();
}
},
},
...
</script>

原理

contextBridge 模块可以安全地暴露 您在独立运行的预加载脚本中提供的API 给 网站运行所在的上下文。 API 还可以像以前一样,从 window.myAPI 网站上访问。