electron 网页TodoList应用打包win桌面软件数据持久化

参考:
electron 网页TodoList工具打包成win桌面应用exe
https://blog.csdn.net/weixin_42357472/article/details/140648621

electron直接打包exe应用,打开网页上面添加的task在重启后为空,历史没有被保存,需要持久化工具保存之前的操作记录

这里测试用electron-store或electron-conf两个持久化工具运行都ESM报错:
https://zhuanlan.zhihu.com/p/706281785
在这里插入图片描述

解决方法:
直接使用 Node.js 的 fs 模块直接读写 JSON 文件。这样可以避免 ES modules 的问题。
1)electron配置文件
main.js

const { app, BrowserWindow, ipcMain } = require('electron')
const path = require('path')
const fs = require('fs')const STORAGE_PATH = path.join(app.getPath('userData'), 'todos.json')function saveTodos(todos) {fs.writeFileSync(STORAGE_PATH, JSON.stringify(todos))
}function loadTodos() {try {return JSON.parse(fs.readFileSync(STORAGE_PATH, 'utf8'))} catch (error) {return []}
}function createWindow () {const win = new BrowserWindow({width: 800,height: 600,webPreferences: {nodeIntegration: true,contextIsolation: false}})win.loadFile('index.html')
}app.whenReady().then(() => {createWindow()app.on('activate', () => {if (BrowserWindow.getAllWindows().length === 0) {createWindow()}})
})app.on('window-all-closed', () => {if (process.platform !== 'darwin') {app.quit()}
})// 修改这些 IPC 处理器
ipcMain.on('save-todos', (event, todos) => {saveTodos(todos)
})ipcMain.handle('load-todos', () => {return loadTodos()
})

package.json

{"name": "todolist-app","version": "1.0.0","main": "main.js","build": {"appId": "com.yourcompany.todolist","mac": {"category": "public.app-category.productivity"},"win": {"icon": "icons/icon.png","target": ["nsis"]},"linux": {"target": ["AppImage","deb"]}},"scripts": {"start": "electron .","build": "electron-builder  --win"},"keywords": [],"author": "","license": "ISC","description": "","devDependencies": {"electron": "^31.2.1","electron-builder": "^24.13.3"},"dependencies": {}
}

2)网页应用
index.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>TodoList</title><link rel="stylesheet" href="styles.css">
</head>
<body><h1>TodoList</h1><form id="todo-form"><input type="text" id="todo-input" placeholder="Enter a new task" required><button type="submit" id="add-button">Add</button></form><ul id="todo-list"></ul><script src="script.js"></script>
</body>
</html>

styles.css

body {font-family: Arial, sans-serif;max-width: 500px;margin: 0 auto;padding: 20px;
}
h1 {text-align: center;
}
#todo-form {display: flex;margin-bottom: 20px;
}
#todo-input {flex-grow: 1;padding: 10px;font-size: 16px;border: 1px solid #ddd;border-radius: 4px 0 0 4px;
}
#add-button {padding: 10px 20px;font-size: 16px;background-color: #4CAF50;color: white;border: none;border-radius: 0 4px 4px 0;cursor: pointer;
}
#todo-list {list-style-type: none;padding: 0;
}
.todo-item {display: flex;align-items: center;padding: 10px;background-color: #f9f9f9;border: 1px solid #ddd;margin-bottom: 10px;border-radius: 4px;
}
.todo-item.completed {text-decoration: line-through;opacity: 0.6;
}
.todo-item input[type="checkbox"] {margin-right: 10px;
}
.delete-button {margin-left: auto;background-color: #f44336;color: white;border: none;padding: 5px 10px;border-radius: 4px;cursor: pointer;
}

script.js

const { ipcRenderer } = require('electron')const todoForm = document.getElementById('todo-form')
const todoInput = document.getElementById('todo-input')
const todoList = document.getElementById('todo-list')async function loadTodos() {const todos = await ipcRenderer.invoke('load-todos')todos.forEach(todo => {addTodoToDOM(todo.text, todo.completed)})
}function saveTodos() {const todos = Array.from(todoList.children).map(li => ({text: li.querySelector('span').textContent,completed: li.classList.contains('completed')}))ipcRenderer.send('save-todos', todos)
}function addTodoToDOM(text, completed = false) {const li = document.createElement('li')li.className = 'todo-item' + (completed ? ' completed' : '')li.innerHTML = `<input type="checkbox" ${completed ? 'checked' : ''}><span>${text}</span><button class="delete-button">Delete</button>`li.querySelector('input[type="checkbox"]').addEventListener('change', function() {li.classList.toggle('completed')if (li.classList.contains('completed')) {todoList.appendChild(li)} else {todoList.insertBefore(li, todoList.firstChild)}saveTodos()})li.querySelector('.delete-button').addEventListener('click', function() {li.remove()saveTodos()})if (completed) {todoList.appendChild(li)} else {todoList.insertBefore(li, todoList.firstChild)}
}todoForm.addEventListener('submit', function(e) {e.preventDefault()if (todoInput.value.trim() === '') returnaddTodoToDOM(todoInput.value)saveTodos()todoInput.value = ''
})loadTodos()

打包:

npm run build

在这里插入图片描述
完成在dist下生产安装文件,及win-unpacked 无需安装的解压文件
在这里插入图片描述
在这里插入图片描述
点击exe运行即可
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/49787.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从数据时代到智能时代,星环科技信雅达联合发布金融全栈解决方案

近年来&#xff0c;星环科技与信雅达在金融行业的多个关键领域展开了广泛而深入的合作&#xff0c;推出了一系列面向金融科技领域的联合解决方案。此次合作基于星环科技在大数据、人工智能和云计算领域的先进技术&#xff0c;以及信雅达在金融领域的深厚积累&#xff0c;围绕数…

nms概念

nms基本概念&#xff1a;非极大值抑制 用途&#xff1a;在做目标检测的时候&#xff0c;往往会生成很多很多候选框&#xff0c;在做目标检测的时候&#xff0c;往往会生成很多很多候选框。 处理流程&#xff1a; 1.对某一类按score对候选框进行排序&#xff0c;并选出score最…

META 备受期待的 Llama 3 405B 即将发布

本心、输入输出、结果 文章目录 META 备受期待的 Llama 3 405B 即将发布前言Llama 3 405B或许会彻底改变专用模型的数据质量Llama 3 405B将形成新的模型生态系统:从基础模型到专家组合Llama 3 405B有最高效 API 的竞争Llama 3 405B 基准测试META 备受期待的 Llama 3 405B 即将…

【Unity国产化信创平台】麒麟银河V10系统虚拟机创建

目录 一、麒麟V10系统镜像下载 二、虚拟机创建流程 三、麒麟银河系统安装流程 一、麒麟V10系统镜像下载 https://www.kylinos.cn/# 官方访问还是会有问题&#xff0c;如果有需要麒麟银河Kylin系统V10的镜像文件&#xff0c;可以留下邮箱或者私信博主获取。 二、虚拟机创…

SpringBoot3 JDK21 Vue3开源后台RBAC管理系统 | 2024年好用的开源RBAC管理系统 | 数据权限的探索

序言 项目现已全面开源&#xff0c;商业用途完全免费&#xff01; 当前版本&#xff1a;v0.7.2。 如果喜欢这个项目或支持作者&#xff0c;欢迎Star、Fork、Watch 一键三连 &#x1f680;&#xff01;&#xff01; 在构建此代码框架的过程中&#xff0c;我已投入了大量精力&…

Nginx Proxy缓存

Proxy缓存 缓存类型 网页缓存 &#xff08;公网&#xff09;CDN数据库缓存 memcache redis网页缓存 nginx-proxy客户端缓存 浏览器缓存 模块 ngx_http_proxy_module 语法 缓存开关 Syntax: proxy_cache zone | off; Default: proxy_cache off; Context: http,…

Android Studio Build窗口出现中文乱码问题

刚安装成功的android studio软件打开工程&#xff0c;编译时下方build窗口中中文是乱码。 解决&#xff1a; 可点击studio状态栏的Help—>Edit Custom VM Options &#xff0c;在打开的studio64.exe.vmoptions文件后面添加&#xff1a;(要注意不能有空格&#xff0c;否则st…

科技前沿:Llama 3.1的突破与革新

在科技的长河中&#xff0c;每一次模型的更新都是对人类智慧的致敬。今天&#xff0c;我们将聚焦于Meta公司最新发布的Llama 3.1系列模型&#xff0c;探索其在AI领域的前沿突破。 新模型的诞生 自去年以来&#xff0c;Meta公司不断推进人工智能技术的发展&#xff0c;终于在近…

Visual Studio 2022新建 cmake 工程测试 opencv helloworld

1. 参考博客&#xff1a; 1.1. https://blog.csdn.net/yangSHU21/article/details/130237669( 利用OpenCV把一幅彩色图像转换成灰度图 )( vs2022_cmake_test.cpp 中的代码用的此博客的&#xff0c;就改了下图片文件路径而已 ) 2. 检查 Visual Studio 2022是否支持 cmake&#…

大数据之Oracle同步Doris数据不一致问题

数据同步架构如下&#xff1a; 出现的问题&#xff1a; doris中的数据条数 源库中的数据条数 总数完全不一致。 出现问题的原因&#xff1a; 在Dinky中建立表结构时&#xff0c;缺少对主键属性的限制 primary key(ID) not enforced 加上如上语句&#xff0c;数据条数解决一致 …

Internxt:适用于Linux开源安全云存储平台

有无数的云存储平台为您的文件提供安全可靠的存储空间。可在 Linux 上安装的热门云存储应用程序包括Dropbox、Nextcloud和Google Drive&#xff0c;遗憾的是&#xff0c;后者迄今为止不提供 Linux 客户端。 其他自托管选项包括OwnCloud、Pydio Cells、Seafile、Resilio和Synct…

matlab 小数取余 rem 和 mod有 bug

目录 前言Matlab取余函数1 mod 函数1.1 命令行输入1.2 命令行输出 2 rem 函数2.1 命令行输入2.2 命令行输出 分析原因注意 前言 在 Matlab 代码中mod(0.11, 0.1) < 0.01 判断为真&#xff0c;mod(1.11, 0.1) < 0.01判断为假&#xff0c;导致出现意料外的结果。 结果发现…

Leetcode509. 斐波那契数(递归和常规两种写法)

问题描述&#xff1a; 斐波那契数 &#xff08;通常用 F(n) 表示&#xff09;形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始&#xff0c;后面的每一项数字都是前面两项数字的和。也就是&#xff1a; F(0) 0&#xff0c;F(1) 1 F(n) F(n - 1) F(n - 2)&#xff0c;…

走进数组的奇妙之旅(1)-学习笔记

引言&#xff1a; 在前几篇文章中&#xff0c;我们深入探讨了函数的奥秘。在讲述函数知识的过程中&#xff0c;我们邂逅了一个新的概念&#xff0c;你或许还记得在演示 strcpy函数时&#xff0c;出现的这行代码&#xff1a;char1[20]{0};。当时&#xff0c;你是否感到好奇&…

软考中级网络工程师考什么?应该怎么正确备考

网络工程师软考中级难易度50%&#xff0c;不太难。但是如果准备不足就悬了&#xff0c;赶紧备考起来吧。 网络工程师每年考两次&#xff0c;相比其他的软考考试一年中考的机会又多了一次&#xff0c;而且软考网工也是挺热门的科目&#xff0c;每年很多人报考&#xff0c;相对的…

视觉语言动作模型:从网页知识到机器人控制的实战RT-2

作者&#xff1a; Anthony Brohan, Noah Brown, Justice Carbajal, Yevgen Chebotar, Xi Chen, Krzysztof Choromanski, Tianli Ding, Danny Driess, Avinava Dubey, Chelsea Finn, Pete Florence, Chuyuan Fu, Montse Gonzalez Arenas, Keerthana Gopalakrishnan, Kehang Han…

【深度学习】PyTorch框架(5):Transformer和多注意力机制

1、引言 在本文中&#xff0c;我们将探讨近两年来最具影响力的模型架构之一——Transformer模型。自从2017年Vaswani等人发表的论文《注意力是你所需要的全部》以来&#xff0c;Transformer架构在多个领域持续刷新着性能记录&#xff0c;尤其是在自然语言处理&#xff08;NLP&…

CSI-RS在信道中传输的过程

简单介绍CSI-RS信号生成&#xff0c;在信道中传输和接收的过程 1.载波配置 首先需要配置载波相关的参数 系统带宽和子载波间隔 5G NR中&#xff0c;系统带宽和子载波间隔是两个关键参数&#xff0c;共同决定无线资源的分配和使用 系统带宽 5G NR支持广泛的系统带宽&…

碳酸锂溶液树脂吸附除钙镁的方法和工艺流程

碳酸锂溶液作为一种重要的化工原料&#xff0c;主要用于锂电池的制造和其他化学合成过程。它对纯度有较高要求&#xff0c;因此在制备和处理过程中&#xff0c;去除杂质如钙镁离子是非常关键的步骤。 关于碳酸锂溶液除钙镁的方法&#xff0c;几种常见的处理技术包括沉淀法、离…

C++ | Leetcode C++题解之第264题丑数II

题目&#xff1a; 题解&#xff1a; class Solution { public:int nthUglyNumber(int n) {vector<int> dp(n 1);dp[1] 1;int p2 1, p3 1, p5 1;for (int i 2; i < n; i) {int num2 dp[p2] * 2, num3 dp[p3] * 3, num5 dp[p5] * 5;dp[i] min(min(num2, num3…