当前位置: 首页 > news >正文

electron27-react-mateos:基于electron+react18仿matePad桌面系统

基于Electron27+React18+ArcoDesign搭建桌面版OS管理系统。

electron-react-mateos 基于最新前端跨端技术栈electron27.x+react18+arco-design+zustand4+sortablejs构建的一款仿制matePad界面多层级路由管理OS系统。

在这里插入图片描述
在这里插入图片描述
ElectronReactOS支持桌面多路由配置,新开窗口+弹窗开启路由页面。

在这里插入图片描述

在这里插入图片描述

使用技术

  • 编码开发:vscode
  • 框架技术:electron27+vite4+react18+zustand+react-router
  • 打包工具:electron-builder^24.6.4
  • 组件库:arco-design (字节react轻量级UI组件库)
  • 拖拽组件:sortablejs
  • 模拟请求:axios
  • 弹窗组件:rdialog (基于react多功能layer弹窗)
  • 美化滚动条:rscroll (基于react虚拟滚动条组件)

在这里插入图片描述
如何使用electron27创建多窗口,可以去看看这篇分享文章。

https://blog.csdn.net/yanxinyun1990/article/details/134047329

在这里插入图片描述

项目结构目录

使用vite4构建工具创建react18项目,遵循react hooks语法编码开发。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

electron+react桌面布局

在这里插入图片描述
桌面分为顶部栏+桌面端路由菜单+底部Dock菜单三大模块。

<div className="radmin__layout flexbox flex-col">{/* 导航栏 */}<Header />{/* 桌面区域 */}<div className="ra__layout-desktop flex1 flexbox" onContextMenu={handleDeskCtxMenu} style={{marginBottom: 70}}><DeskMenu /></div>{/* Dock菜单 */}<Dock />
</div>

electron实现dock菜单

在这里插入图片描述
在这里插入图片描述
dock菜单采用背景滤镜模糊效果、支持自适应伸缩、拖拽排序等功能。

<div className="ra__docktool"><div className={clsx('ra__dock-wrap', !dock ? 'compact' : 'split')}>{dockMenu.map((res, key) => {return (<div key={key} className="ra__dock-group">{ res?.children?.map((item, index) => {return (<a key={index} className={clsx('ra__dock-item', {'active': item.active, 'filter': item.filter})} onClick={() => handleDockClick(item)}><span className="tooltips">{item.label}</span><div className="img">{ item.type != 'icon' ? <img src={item.image} /> : <Icon name={item.image} size={32} style={{color: 'inherit'}} /> }</div></a>)})}</div>)})}</div>
</div>
const dockMenu = [{// 图片图标children: [{label: 'Safari', image: '/static/mac/safari.png', active: true},{label: 'Launchpad', image: '/static/mac/launchpad.png'},{label: 'Contacts', image: '/static/mac/contacts.png'},{label: 'Messages', image: '/static/mac/messages.png', active: true}]},{// 自定义iconfont图标children: [{label: 'Home', image: <IconDesktop />, type: 'icon'},{label: 'About', image: 've-icon-about', type: 'icon'}]},{children: [{label: 'Appstore', image: '/static/mac/appstore.png'},{label: 'Mail', image: '/static/mac/mail.png'},{label: 'Maps', image: '/static/mac/maps.png', active: true},{label: 'Photos', image: '/static/mac/photos.png'},{label: 'Facetime', image: '/static/mac/facetime.png'},{label: 'Calendar', image: '/static/mac/calendar.png'},{label: 'Notes', image: '/static/mac/notes.png'},{label: 'Calculator', image: '/static/mac/calculator.png'},{label: 'Music', image: '/static/mac/music.png'}]},{children: [{label: 'System', image: '/static/mac/system.png', active: true, filter: true},{label: 'Empty', image: '/static/mac/bin.png', filter: true}]}
]// 点击dock菜单
const handleDockClick = (item) => {const { label } = itemif(label == 'Home') {createWin({title: '首页',route: '/home',width: 900,height: 600})}else if(label == 'About') {setWinData({ type: 'CREATE_WIN_ABOUT' })}else if(label == 'System') {createWin({title: '网站设置',route: '/setting/system/website',isNewWin: true,width: 900,height: 600})}
}useEffect(() => {const dockGroup = document.getElementsByClassName('ra__dock-group')// 组拖拽for(let i = 0, len = dockGroup.length; i < len; i++) {Sortable.create(dockGroup[i], {group: 'share',handle: '.ra__dock-item',filter: '.filter',animation: 200,delay: 0,onEnd({ newIndex, oldIndex }) {console.log('新索引:', newIndex)console.log('旧索引:', oldIndex)}})}
}, [])

electron+react18实现桌面级路由

在这里插入图片描述

/*** Desk桌面多层级路由菜单* Create by andy  Q:282310962
*/export default function DeskMenu() {const t = Locales()const filterRoutes = routes.filter(item => !item?.meta?.isWhite)// 桌面二级菜单弹框const DeskPopup = (item) => {const { key, meta, children } = itemreturn (!meta?.isHidden &&<RScroll maxHeight={220}><div className="ra__deskmenu-popup__body">{ children.map(item => {if(item?.children) {return DeskSubMenu(item)}return DeskMenu(item)})}</div></RScroll>)}// 桌面菜单项const DeskMenu = (item) => {const { key, meta, children } = itemreturn (!meta?.isHidden &&<div key={key} className="ra__deskmenu-block"><a className="ra__deskmenu-item" onClick={()=>handleDeskClick(item)} onContextMenu={handleDeskCtxMenu}><div className="img">{meta?.icon ?isImg(meta?.icon) ? <img src={meta.icon} /> : <Icon name={meta.icon} size={40} />:<Icon name="ve-icon-file" size={40} />}</div>{ meta?.name && <span className="title clamp2">{t[meta.name]}</span> }</a></div>)}// 桌面二级菜单项const DeskSubMenu = (item) => {const { key, meta, children } = itemreturn (!meta?.isHidden &&<div key={key} className="ra__deskmenu-block"><a className="ra__deskmenu-item group" onContextMenu={e=>e.stopPropagation()}><Popovertitle={<div className="ra__deskmenu-popup__title">{meta?.name && t[meta.name]}</div>}content={() => DeskPopup(item)}trigger="hover"position="right"triggerProps={{popupStyle: {padding: 5},popupAlign: {right: [10, 45]},mouseEnterDelay: 300,// showArrow: false}}style={{zIndex: 100}}><div className="img">{children.map((child, index) => {if(child?.meta?.isHidden) returnreturn child?.meta?.icon ?isImg(child?.meta?.icon) ? <img key={index} src={child.meta.icon} /> : <Icon key={index} name={child.meta.icon} size={10} />:<Icon key={index} name="ve-icon-file" size={10} />})}</div></Popover>{ meta?.name && <span className="title clamp2">{t[meta.name]}</span> }</a></div>)}// 点击dock菜单const handleDeskClick = (item) => {const { key, meta, element } = itemconst reg = /[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+\.?/if(reg.test(key)) {window.open(key)}else {if(meta?.isNewWin) {// 新窗口打开createWin({title: t[meta?.name] || meta?.title,route: key,width: 900,height: 600})}else {// 弹窗打开rdialog({title: t[meta?.name] || meta?.title,content: <BrowserRouter>{element}</BrowserRouter>,maxmin: true,showConfirm: false,area: ['900px', '550px'],className: 'rc__dialogOS',customStyle: {padding: 0},zIndex: 100})}}}// 右键菜单const handleDeskCtxMenu = (e) => {e.stopPropagation()let pos = [e.clientX, e.clientY]rdialog({type: 'contextmenu',follow: pos,opacity: .1,dialogStyle: {borderRadius: 3, overflow: 'hidden'},btns: [{text: '打开'},{text: '重命名/配置'},{text: '删除',click: () => {rdialog.close()}}]})}useEffect(() => {const deskEl = document.getElementById('deskSortable')Sortable.create(deskEl, {handle: '.ra__deskmenu-block',animation: 200,delay: 0,onEnd({ newIndex, oldIndex }) {console.log('新索引:', newIndex)console.log('旧索引:', oldIndex)}})}, [])return (<div className="ra__deskmenu" id="deskSortable">{ filterRoutes.map(item => {if(item?.children) {return DeskSubMenu(item)}return DeskMenu(item)})}</div>)
}

好了,以上就是electron+react18开发桌面os的一些知识分享。

https://blog.csdn.net/yanxinyun1990/article/details/132825719

https://blog.csdn.net/yanxinyun1990/article/details/131408928

在这里插入图片描述

相关文章:

electron27-react-mateos:基于electron+react18仿matePad桌面系统

基于Electron27React18ArcoDesign搭建桌面版OS管理系统。 electron-react-mateos 基于最新前端跨端技术栈electron27.xreact18arco-designzustand4sortablejs构建的一款仿制matePad界面多层级路由管理OS系统。 ElectronReactOS支持桌面多路由配置&#xff0c;新开窗口弹窗开启路…...

高精度算法总结

高精度加法 题目链接&#xff1a; https://www.acwing.com/activity/content/problem/content/825/ 代码模版&#xff1a; #include <iostream> #include <vector>using namespace std;// C A B vector<int> add(vector<int> &A, vector<…...

EMQX-5.3.1单机集群部署并基于Nginx实现负载均衡

本例单机集群部署使用三个节点&#xff0c;分别为node1、node2、node3 一、安装与配置 1 创建数据目录 mkdir -p node1/data node1/logs mkdir -p node2/data node2/logs mkdir -p mode3/data node3/logs 2 数据目录授权 chown 1000 node1/ node2/ node3/ chown 1000 n…...

电商又有大动静,又一短视频进军电商领域!

我是电商珠珠 电商近几年来发展迅速&#xff0c;截止到23年的10月26日&#xff0c;电商零售平台市场份额是淘宝市场占比的53%&#xff0c;京东为20%&#xff0c;拼多多手握15%的市场占比&#xff0c;三者合计份额已经达到了88%。 剩下的抖音、快手、苏宁也在奋力抢占更多。 …...

C语言线性表的链式存储(框架)

线性表的链式存储 线性表的顺序存储&#xff1a;用一块连续的内存空间 线性表的链式存储&#xff1a;不连续的内存空间 链表是由一系列的节点组成&#xff0c;每个节点包含两个域&#xff0c;一个是数据域&#xff0c;一个是指针域 链表的插入和删除原理 单项链表框架的搭建 …...

webpack配置完热更新之后还是会刷新整个页面

可以在webpack文档中找到有关热更新的详细信息&#xff0c;意思就是&#xff0c;开启热更新之后&#xff0c;整个页面你改了哪里&#xff0c;就只更新哪里&#xff0c;其他没变的&#xff0c;或者保存在缓存里面的内容&#xff0c;都不会改变&#xff0c;感谢很神奇&#xff01…...

2023年第六届传智杯程序设计挑战赛(个人赛)B组 赛后复盘

传智杯赛后复盘 大家好 我是寸铁&#x1f44a; 2023年第六届传智杯程序设计挑战赛&#xff08;个人赛&#xff09;B组 赛后复盘 喜欢的小伙伴可以点点关注 &#x1f49d; 1. 字符串拼接 细节&#xff1a;一定要清楚nextLine()和next()的区别 nextLine()是遇到回车会停下来 nex…...

C语言——深入理解指针(2)

目录 1. 数组名 2. 指针访问数组 3. 一维数组的传参&#xff08;本质&#xff09; 4. 冒泡排序 5. 二级指针 6. 指针数组&#xff08;指针的数组&#xff09; 7. 指针数组模拟二维数组 1. 数组名 在之前的代码中我们使用指针访问过数组的内容。 int arr[10] {1,2,3,4…...

【已解决】HBase 2.2.6 集群部署后,从节点未启动 HRegionServer

问题发现 今天搭建了 HBase 2.2.6 集群环境&#xff0c;启动之后发现&#xff0c;从节点的 HRegionServer 未启动。多次对比参数设置仍然未发现异常。而启动之前的 HBase 2.4.11 则完成正常&#xff0c;我就有点怀疑是不是 HBase 2.2.6 集群搭建有什么特殊的地方&#xff1f; …...

JVM——垃圾回收(方法区中的垃圾回收和(堆回收)自动垃圾回收)

目录 1.自动垃圾回收介绍1.C/C的内存管理2.Java的内存管理3.垃圾回收的对比 2.方法区的回收方法区的回收 – 手动触发回收 3.堆回收1.引用计数法2.可达性分析算法 1.自动垃圾回收介绍 1.C/C的内存管理 ⚫ 在C/C这类没有自动垃圾回收机制的语言中&#xff0c;一个对象如果不再…...

Flink 常用物理分区算子(Physical Partitioning)

Flink 物理分区算子(Physical Partitioning) 在Flink中&#xff0c;常见的物理分区策略有&#xff1a;随机分配(Random)、轮询分配(Round-Robin)、重缩放(Rescale)和广播(Broadcast)。 接下来&#xff0c;我们通过源码和Demo分别了解每种物理分区算子的作用和区别。 (1) 随机…...

Leetcode.560 和为 K 的子数组

题目链接 Leetcode.560 和为 K 的子数组 mid 题目描述 给你一个整数数组 n u m s nums nums 和一个整数 k k k &#xff0c;请你统计并返回 该数组中和为 k k k 的子数组的个数 。 子数组是数组中元素的连续非空序列。 示例 1&#xff1a; 输入&#xff1a;nums [1,1,1]…...

linklab phase1 更简单的方法

直接反汇编phase1.o&#xff0c;看eax中是0x21&#xff0c;0x21在数据域中&#xff0c;直接把从第21个字节的内容改为0000000000即可。...

8.前端--CSS-文本属性【2023.11.26】

CSS Text&#xff08;文本&#xff09;属性可定义文本的外观&#xff0c;比如文本的颜色、对齐文本、修饰文本、文本缩进、行间距等 1.文本颜色 color 属性用于定义文本的颜色。 语法&#xff1a; div { color: red; }属性&#xff1a; 2.文本对齐 text-align 属性用于设置元…...

容器技术——Cgroup

目录 容器技术容器技术概述要区分好共享与隔离的概念容器技术的三大核心容器对比虚拟机 namespaceUnionFs容器操作系统的来源操作系统的来源完整操作系统的镜像docker image是什么&#xff1f;如何构成的 如何为容器安装操作系统UnionFS&#xff08;联合文件系统&#xff09;的…...

uniapp+vue3路由跳转传参

在uni-app中使用Vue 3进行路由跳转传参&#xff0c;可以通过以下步骤实现&#xff1a; 1.在router文件夹中创建一个名为index.js的文件&#xff0c;用于配置路由。在这个文件中&#xff0c;我们将导入createRouter和createWebHistory函数&#xff0c;并定义路由规则。同时&…...

流量主如何在广告收益和用户体验中找到平衡

流量主在广告收益和用户体验之间找到平衡是一个关键的挑战&#xff0c;因为过多或不恰当的广告可能会影响到用户的满意度和留存率。以下是一些方法&#xff0c;可以帮助流量主在这两者之间找到平衡&#xff1a; admaoyan猫眼聚合 优质内容为先&#xff1a; 提供高质量、有价值的…...

RPC和HTTP的区别

目录 1、RPC是什么 1.1 概念 1.2 RPC的组成部分 1.3 常见的 RPC 技术和框架 1.4 RPC的工作流程 2、HTTP是什么 2.1 概念 2.2 HTTP的消息格式 2.3 HTTP响应状态码有哪些 3、⭐RPC和HTTP的区别 小结 1、RPC是什么 1.1 概念 RPC&#xff08;Remote Procedure Call&am…...

Dubbo3使用Zookeeper作为注册中心的方案讨论!详解DubboAdmin与PrettyZoo来监控服务的优劣!

文章目录 一&#xff1a;Dubbo注册中心的基本使用 二&#xff1a;Zookeeper注册中心的使用 1&#xff1a;依赖引入 2&#xff1a;实际开发 三&#xff1a;Zookeeper作为注册中心的使用展示 1&#xff1a;启动注册Zookeeper服务 2&#xff1a;引入注册中心 (一)&#xf…...

前端uni微信小程序和后端nodejs使用websoket

需求 前端向后台服务器发请求获取验证码&#xff0c;然后端游输入验证码&#xff0c;向我的后端发请求获取验证信息。后台给游戏端返回信息的时候同时给微信小程序端返回验证结果。意思是不要微信小程序端主动触发&#xff0c;验证是否绑定的请求。 思路 后端生成验证码时存…...

Android Wi-Fi 连接失败日志分析

1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分&#xff1a; 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析&#xff1a; CTR…...

利用ngx_stream_return_module构建简易 TCP/UDP 响应网关

一、模块概述 ngx_stream_return_module 提供了一个极简的指令&#xff1a; return <value>;在收到客户端连接后&#xff0c;立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量&#xff08;如 $time_iso8601、$remote_addr 等&#xff09;&a…...

简易版抽奖活动的设计技术方案

1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...

练习(含atoi的模拟实现,自定义类型等练习)

一、结构体大小的计算及位段 &#xff08;结构体大小计算及位段 详解请看&#xff1a;自定义类型&#xff1a;结构体进阶-CSDN博客&#xff09; 1.在32位系统环境&#xff0c;编译选项为4字节对齐&#xff0c;那么sizeof(A)和sizeof(B)是多少&#xff1f; #pragma pack(4)st…...

【JVM】- 内存结构

引言 JVM&#xff1a;Java Virtual Machine 定义&#xff1a;Java虚拟机&#xff0c;Java二进制字节码的运行环境好处&#xff1a; 一次编写&#xff0c;到处运行自动内存管理&#xff0c;垃圾回收的功能数组下标越界检查&#xff08;会抛异常&#xff0c;不会覆盖到其他代码…...

【解密LSTM、GRU如何解决传统RNN梯度消失问题】

解密LSTM与GRU&#xff1a;如何让RNN变得更聪明&#xff1f; 在深度学习的世界里&#xff0c;循环神经网络&#xff08;RNN&#xff09;以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而&#xff0c;传统RNN存在的一个严重问题——梯度消失&#…...

【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制

使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下&#xff0c;限制某个 IP 的访问频率是非常重要的&#xff0c;可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案&#xff0c;使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...

基于Java+VUE+MariaDB实现(Web)仿小米商城

仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意&#xff1a;运行前…...

【WebSocket】SpringBoot项目中使用WebSocket

1. 导入坐标 如果springboot父工程没有加入websocket的起步依赖&#xff0c;添加它的坐标的时候需要带上版本号。 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId> </dep…...

从零开始了解数据采集(二十八)——制造业数字孪生

近年来&#xff0c;我国的工业领域正经历一场前所未有的数字化变革&#xff0c;从“双碳目标”到工业互联网平台的推广&#xff0c;国家政策和市场需求共同推动了制造业的升级。在这场变革中&#xff0c;数字孪生技术成为备受关注的关键工具&#xff0c;它不仅让企业“看见”设…...