electron-updater实现electron全量更新和增量更新——渲染进程交互部分

news2024/9/22 3:51:30

同学们可以私信我加入学习群!


正文开始

  • 前言
  • 更新功能所有文章汇总
  • 一、监听页面渲染完毕
    • 1.1 myApi.handleCheckPcUpdate检查更新
    • 1.2myApi.onPcUpdateProgress接收下载信息
    • 1.3myApi.onPcDownloaded监听下载完毕事件
  • 二、立即更新
  • 三、跳过更新
  • 四、打开更新模块
  • 总结


前言

前面已经讲解过electron更新功能的主进程实现、渲染进程UI样式实现、调试更新功能技巧。这篇文章讲解渲染进程的交互逻辑。前端很多交互逻辑都和主进程、UI渲染有关,阅读本文前,建议先行查阅前面的文章。

我们在讲解更新模块的主进程时,提出过更新的完整设计:

第一步:页面渲染完毕,并询问主进程,是否有更新?
第二步:主进程检查更新,并反馈给页面,有更新/无更新。
第三步:如果无更新,页面直接显示提示信息。如果有更新,页面产生交互逻辑,将决定权交给用户,用户决定是否更新。
第四步:用户点击更新,页面将指令发送给主进程,主进程开始执行更新。

现在我们就需要根据上面的过程,实现前端交互。

更新功能所有文章汇总

  1. electron-updater实现electron全量更新和增量更新——主进程部分
  2. electron-updater实现electron全量更新和增量更新——注意事项/技巧汇总
  3. electron-updater实现electron全量更新和增量更新——渲染进程UI部分
  4. electron-updater实现electron全量更新和增量更新——渲染进程交互部分

一、监听页面渲染完毕

onMounted(() => {
// debugger
        myApi.handleCheckPcUpdate().then(res=>{

            setNeedUpdate(res.success && res.needUpdate)
            setIsDownloading(res.success && res.isDownloading)
            hasCheckRs.value=true
            checkRs.value=res.msg || ''
            if(res.success && res.needUpdate && res.version!=getLocalStorage('ignoreVersion') && route.name=='login'){
                setShowUpdate(true)
            }else if(!res.success && route.name=='login'){
                console.log(res)
                // hasCheckRs.value=true
                checkRs.value=res.msg || '找不到更新资源,更新失败,请通过小程序联系管理员'
            }
        })
        myApi.onPcUpdateProgress((_event, info) => {
            // debugger
            update_info.value = info
        })

        myApi.onPcDownloaded(() => {
            update_info.value = {}
            setShowUpdate(false)
            gsap.killTweensOf(".particle");
            particlesList.value.forEach((particle, index) => {
                // 使用GSAP创建动画
                gsap.killTweensOf(particleRefs.value[index]);
            })
            Modal.confirm({
                title: '提示',
                content: '新版本已下载,是否立即安装?',
                onOk: () => {
                    myApi.toPcInstall()
                },
                onCancel: () => {
                    // 取消操作
                }
            })
        })

    })

1.1 myApi.handleCheckPcUpdate检查更新

页面渲染完毕时,就通过调用myApi.handleCheckPcUpdate方法,主动检查一次更新,对应的preload代码如下:

const handleCheckPcUpdate=async () => {
    let files = await ipcRenderer.invoke('check-pc-update')
    return files // 返回结果
}

'check-pc-update’对应的主进程代码在前文讲解过,是一个双向通信。

1.2myApi.onPcUpdateProgress接收下载信息

myApi.onPcUpdateProgress是在被动接收主进程发来的信息,是一个单向通信,对应的preload代码如下:

const onPcUpdateProgress=(callback) => ipcRenderer.on('pc-update-progress', callback)

'pc-update-progress’对应的主进程代码在前文讲解过,这是一个单向通信,主进程到渲染进程。

1.3myApi.onPcDownloaded监听下载完毕事件

在这里主要做的是初始化下载信息、关闭窗口、关闭gsap注册的动画、提示是否安装。如果用户确认安装,则调用myApi.toPcInstall()方法,myApi.toPcInstall()对应的preload方法是:

const toPcInstall= () => ipcRenderer.invoke('pc-install')

'pc-install’对应的主进程代码在前文奖结果,主要是打开自动安装属性,并检查更新并安装。这里可以是单向通信,我懒得改了。

二、立即更新

在这里插入图片描述

点击立即更新,调用startUpdate,创建粒子动画,并且调用执行更新的方法。

    function startUpdate() {
        createParticle(200)
        setTimeout(() => {
            createAnimation()
            myApi.handlePcToUpdate()
        }, 100)

    }

三、跳过更新

点击跳过更新,调用pauseUpdate,关闭窗口,并且调用检查更新的方法,得到版本号,将版本号记录在浏览器缓存。

    async function pauseUpdate() {
        setShowUpdate(false)
        myApi.handleCheckPcUpdate().then(res=>{
            setLocalStorage('ignoreVersion', res.version)
        })

    }

在onMounted中,myApi.handleCheckPcUpdate()方法调用成功后,会判断ignoreVersion,以此来判断是否在页面渲染后,显示更新模块。

四、打开更新模块

跳过更新后,还需要给用户一个能打开更新模块的途径。
在这里插入图片描述
点击图片里的下载按钮,就会通过调用setShowUpdate,打开更新。

   setShowUpdate(value){
            this.showUpdate=value
        },

如果在登录页面关闭的弹框已经开始更新任务,那么这里应该也显示相同的进度。这就要求全局只有一个更新组件UpdateProgress.vue。并且这个组件的状态在不同的页面都有控制。

这就是典型的全局状态管理应用场景。所以组件的needUpdate(是否需要更新)、showUpdate(显示更新弹框)、version(软件版本号)、isDownloading(是否正在下载)就都维护在全局状态管理文件store/update.js中。

    state:()=>({
        // 是否需要更新
        needUpdate:false,
        showUpdate:false,
        version:0,
        isDownloading:false
    }),

当软件需要更新,或者软件正在更新时,则标题栏显示那个下载图标,代码如下:

     <template v-if="getNeedUpdate() || getIsdownloading()">
              <Icon id="update-arrow" color="#ff9900" style="cursor: pointer" type="md-download" @click="setShowUpdate(true)"/>
     </template>

总结

本文主要是讲解了更新模块的页面交互实现,至此,更新功能的主进程、渲染进程、调试技巧就都告一段落。在开发更新模块的过程中,需要经常操作nginx部署文件服务器,修改参数更新服务等操作,博主开发的中二少年工具箱中的nginx管理工具提供了很大帮助。简单地点点按钮,就能打开部署文件夹、修改下载速率、打开站点查看服务启动情况。

大家如果需要联系博主,或者获取博主各系列文章对应的资源,可以通过私信博主来获取。

有任何前端项目、demo、教程需求,都可以联系博主,博主会视精力更新,免费的羊毛,不薅白不薅!~

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

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

相关文章

打卡第32天------动态规划

坚持了一个月了,骑马找马,要坚持不懈呀✊ 一、动态规划理论基础 1、什么是动态规划?英文:Dynamic Programming,简称DP。 如果某一问题有很多重叠子问题,使用动态规划是最有效的。 所以动态规划中每一个状态一定是由上一个状态推导出来的,这一点就区分于贪心,贪心没有…

JVM—虚拟机类加载时机与过程

参考资料&#xff1a;深入理解Java虚拟机&#xff1a;JVM高级特性与最佳实践&#xff08;第3版&#xff09;周志明 1. 类加载的时机 一个类型从被加载到虚拟机内存开始&#xff0c;到卸载出内存为止&#xff0c;它的生命周期会经历加载、验证、准备、解析、初始化、使用、卸载…

netapp内网穿透

1. 注册netapp账号 NATAPP-内网穿透 基于ngrok的国内高速内网映射工具 2. 购买隧道&#xff0c;要求不高的话可以使用这个免费的 3.设置隧道 主要设置你想通过公网访问你的本地端口号 4.点击我的隧道&#xff0c;注意这里的authtoken&#xff0c;后面会用到 5.本地下载netap…

[E二叉树] lc572. 另一棵树的子树(dfs+前中序判断+树哈希+树上KMP+好题)

文章目录 1. 题目来源2. 题目解析 1. 题目来源 链接&#xff1a;572. 另一棵树的子树 2. 题目解析 看到这个题目就感觉不简单&#xff0c;因为写了写 dfs 版本的&#xff0c;发现好像不太会… 还是简单粗暴一点&#xff0c;直接搞一个 前序中序&#xff0c;进行判断即可。我…

应急响应-Web3

打开虚拟机之后&#xff0c;运行解题系统&#xff1a; 共有三个问题&#xff01; 攻击者的两个IP地址 首先我们看到机器的桌面上还是存在phpstudy&#xff0c;那就还是先去看看是不是从web层面进行的攻击&#xff0c;上传webshell从而getshell。 利用D盾尝试对phpstudy目录进…

Python | Leetcode Python题解之第319题灯泡开关

题目&#xff1a; 题解&#xff1a; class Solution:def bulbSwitch(self, n: int) -> int:return int(sqrt(n 0.5))

redis面试(四)持久化

什么是持久化&#xff1f; 由于redis是基于内存操作的轻量型数据库&#xff0c;所以如果发生宕机重启这种事情&#xff0c;存储的数据就会直接丢失&#xff0c;如果在里面存储了没有备份的数据&#xff0c;那么确实会对我们的业务造成一定影响。 所以我们要通过持久化的手段&a…

Java中interrupted()与isInterrupted()的区别

Java中interrupted&#xff08;&#xff09;与isInterrupted&#xff08;&#xff09;的区别 1、interrupted()方法1.1 示例 2、isInterrupted() 方法2.1 示例 3、总结 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 在Java多线程编程中&a…

手持式气象站:科技赋能精准气象观测

在自然界与人类社会的交织中&#xff0c;气象条件始终扮演着至关重要的角色。无论是农业生产、城市建设&#xff0c;还是日常生活、户外活动&#xff0c;都离不开对天气变化的准确预测和及时响应。随着科技的飞速发展&#xff0c;气象观测设备也迎来了变化&#xff0c;其中&…

什么是人工智能 (AI)

1955年9月&#xff0c;达特茅斯学院&#xff08;Dartmouth College&#xff09;年轻的数学助理教授约翰麦卡锡&#xff08;John McCarthy&#xff09;大胆提出&#xff0c;“原则上&#xff0c;学习的各个方面或智力的任何其他特征都可以被精确地描述&#xff0c;以至于可以制造…

使用Python3脚本检查节假日并通过企业微信发送每日信息

文章目录 简介环境配置企业微信机器人创建群聊设置机器人信息 脚本详解导入必要的库获取节假日信息判断是否为工作日或节假日获取天气预报获取每日一句发送消息到微信主函数 加入定时任务总结完整代码 简介 在日常工作和生活中&#xff0c;自动化任务可以帮助我们节省大量时间…

吃惊!这个Windows双系统方法逆天了|UEFI篇

前言 最近小白在折腾别的系统教程&#xff0c;偶然间发现居然有一个很nice的Windows双系统教程。于是于是&#xff0c;果断尝试了一下&#xff0c;发现真的很可行&#xff01; 这个双系统的办法并不需要使用到WinPE系统&#xff0c;因此并不需要使用到U盘&#xff0c;只需要在…

科普文:微服务之SpringBoot性能优化器动态线程池【Dynamic-Tp】特性和源码解读

一、简述 gitee地址&#xff1a;https://gitee.com/yanhom/dynamic-tp github地址&#xff1a;https://github.com/lyh200/dynamic-tp dynamic-tp是一个轻量级的动态线程池插件&#xff0c;它是一个基于配置中心的动态线程池&#xff0c;线程池的参数可以通过配置中心配置进…

数的三次方根

题目 给定一个浮点数 n&#xff0c;求它的三次方根。 输入格式 共一行&#xff0c;包含一个浮点数 n。 输出格式 共一行&#xff0c;包含一个浮点数&#xff0c;表示问题的解。 注意&#xff0c;结果保留 6 位小数。 数据范围 输入样例&#xff1a; 1000.00 输出样例&a…

征服数据结构中的时间和空间复杂度

目录 时间复杂度推导大O方法求解时间复杂度的方法普通顺序结构单循环双循环递归Master定理&#xff08;主定理&#xff09;递归树方法 空间复杂度 一个算法的好坏根据什么来判断呢&#xff1f;有两种一种是时间效率&#xff0c;一种是空间效率。时间效率也可称为时间复杂度&…

内网穿透--LCX+portmap转发实验

实验背景 通过公司带有防火墙功能的路由器接入互联网&#xff0c;然后由于私网IP的缘故&#xff0c;公网 无法直接访问内部web服务器主机&#xff0c;通过内网其它主机做代理&#xff0c;穿透访问内网web 服务器主机 实验设备 1. 路由器、交换机各一台 2. 外网 kali 一台&…

网络层和数据链路层的理解

文章目录 网络层IP协议网段划分IP地址数量问题NAT技术DNSICMP协议 数据链路层以太网MTU的影响ARP协议 网络层 作用&#xff1a; 在网络环境中确定消息传输的路径。 主要协议&#xff1a; IP协议。 IP协议 IP协议的基本概念&#xff1a;凡是入网的机器都会有一个IP地址&#…

手机上音乐如何转换成MP3格式?分享5款音频格式转换APP

手机上音乐如何转换成MP3格式&#xff1f;相信很多外出办公或者不经常使用电脑的工作人士&#xff0c;学生党&#xff0c;媒体从业者都有这样的疑惑和需求。不同设备和应用可能支持不同的音频格式&#xff0c;导致某些情况下需要将音乐文件转换为MP3格式以确保兼容性。下面&…

24暑假算法刷题 | Day27 | 贪心算法 I | LeetCode 455. 分发饼干,376. 摆动序列,53. 最大子数组和

目录 455. 分发饼干题目描述题解 376. 摆动序列题目描述题解 53. 最大子数组和题目描述题解 455. 分发饼干 点此跳转题目链接 题目描述 假设你是一位很棒的家长&#xff0c;想要给你的孩子们一些小饼干。但是&#xff0c;每个孩子最多只能给一块饼干。 对每个孩子 i&#x…