在Tauri中能否存储并恢复多窗口的尺寸与位置?
在Tauri中实现多窗口状态的保存与恢复
完全可行,你可以通过监听窗口的位置/尺寸变化事件,将状态持久化到本地存储,再在应用启动时读取这些状态重建窗口。以下是具体实现思路和代码示例:
核心步骤
1. 持久化窗口状态
为每个窗口分配唯一标识(如自定义ID或UUID),监听窗口的resized和moved事件,实时将窗口的位置(x/y)、尺寸(width/height)以及加载的URL保存到本地存储中。推荐使用Tauri官方的tauri-plugin-store插件来处理本地存储,它能简化数据读写操作。
2. 应用启动时恢复窗口
启动应用时,读取本地存储的窗口状态列表,遍历每个状态项,使用WindowBuilder创建对应窗口并设置保存的位置和尺寸。
代码实现
前置准备
首先在项目中添加tauri-plugin-store插件:
cargo add tauri-plugin-store
然后在tauri.conf.json中启用插件:
{ "plugins": { "store": {} } }
前端(JavaScript/TypeScript)代码
// 保存单个窗口的状态 async function saveWindowState(windowId: string) { const currentWindow = await window.appWindow.getCurrent(); const bounds = await currentWindow.getBounds(); const store = await currentWindow.getStore(); let windowsState = (await store.get('windows-state')) as Array<{ id: string; url: string; x: number; y: number; width: number; height: number; }> || []; // 更新或添加当前窗口的状态 const stateIndex = windowsState.findIndex(item => item.id === windowId); const windowUrl = await currentWindow.url(); if (stateIndex !== -1) { windowsState[stateIndex] = { ...windowsState[stateIndex], ...bounds, url: windowUrl }; } else { windowsState.push({ id: windowId, url: windowUrl, ...bounds }); } await store.set('windows-state', windowsState); await store.save(); } // 为窗口绑定状态监听事件 async function setupWindowListeners(windowId: string) { const currentWindow = await window.appWindow.getCurrent(); currentWindow.onResized(() => saveWindowState(windowId)); currentWindow.onMoved(() => saveWindowState(windowId)); // 监听窗口关闭,移除对应状态 currentWindow.onClosed(async () => { const store = await currentWindow.getStore(); let windowsState = (await store.get('windows-state')) as Array<any> || []; windowsState = windowsState.filter(item => item.id !== windowId); await store.set('windows-state', windowsState); await store.save(); }); } // 恢复所有保存的窗口 async function restoreWindows() { const store = await window.appWindow.getStore(); const windowsState = (await store.get('windows-state')) as Array<any> || []; for (const state of windowsState) { await window.appWindow.create({ label: state.id, url: state.url, x: state.x, y: state.y, width: state.width, height: state.height }); } } // 应用初始化逻辑 document.addEventListener('DOMContentLoaded', async () => { const store = await window.appWindow.getStore(); const hasSavedState = await store.has('windows-state'); // 主窗口ID,可自定义 const mainWindowId = 'main-window'; if (!hasSavedState) { // 首次启动,保存主窗口初始状态 await setupWindowListeners(mainWindowId); await saveWindowState(mainWindowId); } else { // 恢复之前的所有窗口 await restoreWindows(); // 为恢复的主窗口绑定监听 await setupWindowListeners(mainWindowId); } });
Rust后端配置
在src-tauri/src/main.rs中注册插件:
fn main() { tauri::Builder::default() .plugin(tauri_plugin_store::Builder::default().build()) .run(tauri::generate_context!()) .expect("Failed to run Tauri application"); }
注意事项
- 窗口唯一标识:确保每个窗口的ID不重复,避免状态覆盖或恢复错误。
- 屏幕边界处理:恢复窗口时可添加逻辑判断,确保窗口位置在当前屏幕可见范围内,防止窗口跑到屏幕外。
- 窗口关闭处理:监听窗口的
closed事件,及时从存储中移除已关闭窗口的状态,避免重启时重复创建。
内容的提问来源于stack exchange,提问作者Snoz3f
相关产品推荐
相关产品推荐

