You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 04:10:41