Flutter中如何使用onWindowFocusChanged()实现数据按需本地存储?
实现窗口焦点触发本地JSON保存的方案
核心实现思路
根据需求,核心是监听窗口焦点/可见性变化事件来触发保存逻辑,同时避免不必要的重复写入。下面分两种常见场景给出具体实现:
1. 浏览器环境(前端网页)
浏览器中可以用visibilitychange事件(覆盖窗口切换、最小化等全场景)或blur事件监听焦点变化,配合防抖函数减少重复保存:
// 你的对象列表 let dataList = [{ id: 1, name: "示例数据" }, { id: 2, name: "测试项" }]; // 防抖函数:避免频繁切换窗口导致多次执行保存 function debounce(func, delay = 300) { let timeoutId; return function() { clearTimeout(timeoutId); timeoutId = setTimeout(func, delay); }; } // 保存逻辑:用localStorage存储JSON(浏览器本地存储方案) function saveData() { try { const jsonStr = JSON.stringify(dataList, null, 2); localStorage.setItem('savedDataList', jsonStr); console.log("数据已自动保存"); } catch (err) { console.error("保存失败:", err); } } // 包装防抖后的保存函数 const debouncedSave = debounce(saveData); // 监听页面可见性变化(推荐,覆盖更多场景) document.addEventListener('visibilitychange', () => { if (document.hidden) { debouncedSave(); } }); // 可选:监听窗口失去焦点事件 window.addEventListener('blur', debouncedSave);
2. 桌面应用环境(如Electron)
如果是基于Node.js的桌面应用,直接用fs模块写入本地JSON文件,同时监听窗口的blur事件:
const fs = require('fs'); const path = require('path'); // 你的对象列表 let dataList = [{ id: 1, name: "示例数据" }, { id: 2, name: "测试项" }]; const savePath = path.join(__dirname, 'data.json'); // 防抖函数 function debounce(func, delay = 300) { let timeoutId; return function() { clearTimeout(timeoutId); timeoutId = setTimeout(func, delay); }; } // 保存逻辑:写入本地JSON文件 function saveData() { try { const jsonStr = JSON.stringify(dataList, null, 2); fs.writeFileSync(savePath, jsonStr, 'utf8'); console.log("数据已保存到本地文件"); } catch (err) { console.error("文件写入失败:", err); } } const debouncedSave = debounce(saveData); // Electron窗口监听焦点变化(假设已获取窗口实例) const mainWindow = require('electron').BrowserWindow.getFocusedWindow(); mainWindow.on('blur', debouncedSave);
优化建议
- 增加修改标记:维护一个
isDirty变量,只有当数据真的被修改时才执行保存,避免无意义的IO操作:let isDirty = false; // 修改数据时设置标记 function modifyItem(id, newProps) { const target = dataList.find(item => item.id === id); if (target) { Object.assign(target, newProps); isDirty = true; } } // 修改保存函数,先检查标记 function saveData() { if (!isDirty) return; // 原有保存逻辑... isDirty = false; } - 定时备份保存:除了焦点变化,添加定时自动保存(比如每5分钟一次),防止窗口一直处于焦点状态时意外崩溃丢失数据。
- 备份旧文件:每次保存前复制一份旧的JSON文件作为备份(如
data.backup.json),避免保存失败导致数据损坏。 - 错误提示:在桌面应用中,保存失败时通过弹窗提示用户,避免静默失败。
内容的提问来源于stack exchange,提问作者Omar Fayad
相关产品推荐
相关产品推荐

