如何在 Electron 中制作多个 Svelte windows?
How to make multiple Svelte windows in Electron?
对于我的电子应用程序,我想打开另一个 Svelte-window(或根据启动变量加载不同的 windows/components)。
假设我使用 this tutorial 设置了一个基本结构,我的 App.svelte
看起来像这样:
<script>
const openLauncher = () => {
window.api.openWindow("launcher");
};
</script>
<button on:click={openLauncher}>Open Launcher</button>
如你所见,我添加了一个IPC功能来打开一个新的window。对应的index.js
:
const { app, BrowserWindow, ipcMain } = require("electron");
const { join } = require("path");
app.on("ready", () => {
const mainWindow = new BrowserWindow({
webPreferences: {
preload: join(__dirname, "./preload.js"),
}
});
mainWindow.loadFile(join(__dirname, "../public/index.html"));
});
ipcMain.on("openLauncher", (event, args) => {
const launcher = new BrowserWindow({
webPreferences: {
preload: join(__dirname, "./preload.js"),
}
});
launcher.loadFile(join(__dirname, "../public/launcher.html"));
});
preload.js
:
const { contextBridge, ipcRenderer } = require("electron");
const API = {
openWindow: (obj) => ipcRenderer.send("openLauncher", obj),
}
contextBridge.exposeInMainWorld("api", API);
这确实有效,并使用 launcher.html
打开一个新的 window,但我不知道如何让 Svelte 组件在该新文件中工作。
我的一个想法是修改 main.js
文件,使 body 组件发生变化,如下所示:
import App from './App.svelte';
import LauncherApp from './LauncherApp.svelte';
const bodyID = document.getElementsByTagName('body')[0].id;
const app = {};
if (bodyID == "index") {
app = new App({
target: document.body,
});
}
else if (bodyID == "launcher") {
app = new LauncherApp({
target: document.body,
});
}
export default app;
这适用于主要 window(即,如果我切换 ID,它会在启动时加载正确的组件)但是因为它在打开新 window 时不会加载任何 Svelte,这不起作用。
所以,如果有任何关于如何让 Svelte 加载 new/different windows/html-files 的想法,我将不胜感激!如果有办法用 SvelteKit 做到这一点,那就更好了!
提前致谢!
我看到的明显的快速修复是在 App.svelte
中的 bodyID
上使用 #if
块,其中包含两个组件,MainApp(App.svelte
的内容)和 LauncherApp,以及然后根据您所处的模式简单地更改 bodyID。
当使用 sveltekit 时,我认为将 LauncherApp 视为一个单独的路径是有意义的(我相信这是使用 sveltekit “分离”页面的唯一方法,尽管我不是 100%)。因此,当打开一个新的 window 时,您将应用程序的新实例导航到 LauncherApp 路由。如果您不想要与主应用程序中相同的基本布局,您可以添加一个 __layout.reset.svelte 文件。
我不知道为什么你的解决方案不起作用,它非常优雅。
对于我的电子应用程序,我想打开另一个 Svelte-window(或根据启动变量加载不同的 windows/components)。
假设我使用 this tutorial 设置了一个基本结构,我的 App.svelte
看起来像这样:
<script>
const openLauncher = () => {
window.api.openWindow("launcher");
};
</script>
<button on:click={openLauncher}>Open Launcher</button>
如你所见,我添加了一个IPC功能来打开一个新的window。对应的index.js
:
const { app, BrowserWindow, ipcMain } = require("electron");
const { join } = require("path");
app.on("ready", () => {
const mainWindow = new BrowserWindow({
webPreferences: {
preload: join(__dirname, "./preload.js"),
}
});
mainWindow.loadFile(join(__dirname, "../public/index.html"));
});
ipcMain.on("openLauncher", (event, args) => {
const launcher = new BrowserWindow({
webPreferences: {
preload: join(__dirname, "./preload.js"),
}
});
launcher.loadFile(join(__dirname, "../public/launcher.html"));
});
preload.js
:
const { contextBridge, ipcRenderer } = require("electron");
const API = {
openWindow: (obj) => ipcRenderer.send("openLauncher", obj),
}
contextBridge.exposeInMainWorld("api", API);
这确实有效,并使用 launcher.html
打开一个新的 window,但我不知道如何让 Svelte 组件在该新文件中工作。
我的一个想法是修改 main.js
文件,使 body 组件发生变化,如下所示:
import App from './App.svelte';
import LauncherApp from './LauncherApp.svelte';
const bodyID = document.getElementsByTagName('body')[0].id;
const app = {};
if (bodyID == "index") {
app = new App({
target: document.body,
});
}
else if (bodyID == "launcher") {
app = new LauncherApp({
target: document.body,
});
}
export default app;
这适用于主要 window(即,如果我切换 ID,它会在启动时加载正确的组件)但是因为它在打开新 window 时不会加载任何 Svelte,这不起作用。
所以,如果有任何关于如何让 Svelte 加载 new/different windows/html-files 的想法,我将不胜感激!如果有办法用 SvelteKit 做到这一点,那就更好了!
提前致谢!
我看到的明显的快速修复是在 App.svelte
中的 bodyID
上使用 #if
块,其中包含两个组件,MainApp(App.svelte
的内容)和 LauncherApp,以及然后根据您所处的模式简单地更改 bodyID。
当使用 sveltekit 时,我认为将 LauncherApp 视为一个单独的路径是有意义的(我相信这是使用 sveltekit “分离”页面的唯一方法,尽管我不是 100%)。因此,当打开一个新的 window 时,您将应用程序的新实例导航到 LauncherApp 路由。如果您不想要与主应用程序中相同的基本布局,您可以添加一个 __layout.reset.svelte 文件。
我不知道为什么你的解决方案不起作用,它非常优雅。