欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 美食 > electron展示下载进度条

electron展示下载进度条

2024/10/28 12:46:24 来源:https://blog.csdn.net/zhoulib__/article/details/143214915  浏览:    关键词:electron展示下载进度条

我们使用electron下载文件时,会发现不像浏览器一样会有地方展示下载进度,这导致下载一些大文件时不知道下载进度到哪里了

下面我们通过electron提供的will-download监听和element-plus中的ElNotificationElProgress组件实现这一功能
在这里插入图片描述

实现逻辑

  1. 触发下载文件这一操作
  2. 监听下载开始、下载进度、下载结束
  3. 根据监听内容操作vnode展示加载进度

1、触发下载文件这一操作

使用electron中ipcMain模块接受页面中发送来的指令

// main.js 部分代码 通过这个打开****.vue界面 
var win = new BrowserWindow();
//  download.js 部分代码
const { ipcMain, dialog } = require('electron')
let filePath = '';// 监听渲染进程发出的download事件
const webContents = win.webContents;ipcMain.on('download', (evt, args) => {const fileArr = args.split("/");let ext = path.extname(args)let filters = [{ name: '全部文件', extensions: ['*'] }]if (ext && ext !== '.') {filters.unshift({name: '',extensions: [ext.match(/[a-zA-Z]+$/)[0]]})}dialog.showSaveDialog(win, {filters,defaultPath:args}).then( res => {if(res.filePath){filePath = res.filePathwebContents.downloadURL(args) // 注意这里必须是下载文件可访问路径。而不是存储路径}})})// vue页面中的逻辑 ***.vueimport { ipcRenderer } from "electron"// 触发var url = '下载地址.***'ipcRenderer.send('download', url)

执行完上面的代码会弹窗另存为下载,会发现下载没有显示进度的地方

2、监听下载开始、下载进度、下载结束

监听webContents中的will-download事件会返回下载相关的一些信息,这里把下载过程中的一些状态和用到的一些参数发送给webContents中打开的页面

// download.js 部分代码webContents.session.on('will-download', (event, item, webContents) => {item.setSavePath(filePath) // 这里是存储路径或者存储文件名称var filName = path.basename(filePath)win.webContents.send('win-will-download',{type:'start',params:{filName}})item.on('updated', (event, state) => {if (state === 'interrupted') {console.log('Download is interrupted but can be resumed')} else if (state === 'progressing') {if (item.isPaused()) {console.log('Download is paused')} else {win.webContents.send('win-will-download',{type:"progress",params:{totalBytes:item.getTotalBytes(),receivedBytes:item.getReceivedBytes()}})}}})item.once('done', (event, state) => {if (state === 'completed') {win.webContents.send('win-will-download',{type:"completed"})console.log('Download successfully')} else {console.log(`Download failed: ${state}`)}})})// ***.vue//download是展示下载进度的组件,下面会有相应的代码 这里通过ref创建响应数据 vue2的话可以通过 Vue.observable API进行创建
import download from "@/components/download/index.vue"
import { ElNotification } from 'element-plus'
import { h, ref } from 'vue'
var totalBytes = ref(0)
var receivedBytes = ref(0)mounted(){ipcRenderer.removeAllListeners('win-will-download')ipcRenderer.on('win-will-download', this.winDownLoadFun)},methods:{winDownLoadFun(event, data) {if (data.type == 'start') {this.notice && this.notice.close && this.notice.close()var progress = h(download, {totalBytes: totalBytes,receivedBytes: receivedBytes,filName: data.params.filName,onClose: () => {totalBytes.value = 0receivedBytes.value = 0this.notice && this.notice.close && this.notice.close()}})this.notice = ElNotification({title: '下载进度',position: 'bottom-right',duration: 0,showClose: false,message: progress,onClose: () => {this.notice = null}})}else if (data.type == 'progress') {totalBytes.value = data.params.totalBytesreceivedBytes.value = data.params.receivedBytes} else if (data.type == 'completed') {receivedBytes.value = totalBytes.value}},} 

3、根据监听内容操作vnode展示加载进度

下面是download/index.vue完整文件

<template><div style="width: 100%;"><div><div @click="$emit('close')" v-if="percentage == 100" style="position: absolute;top: 15px;right: 15px;cursor: pointer;">关闭</div><div class="task-item"><img class="img" src="@/assets/image/zip-1.png"></img><div class="name"><div>{{filName}}</div><div class="progress1">{{limitFormat(receivedBytes.value)}}/{{limitFormat(totalBytes.value)}}</div></div></div><div><el-progress :show-text="false" :percentage="percentage" /></div></div></div>
</template><script>
import { ElMessage, ElProgress } from 'element-plus'
import { ref } from 'vue'
export default {name: 'download',props: {filName:{type:String,default:""},totalBytes: {default() {return ref(0)}},receivedBytes: {default() {return ref(0)}}},computed:{percentage(){return parseFloat((((this.receivedBytes.value / this.totalBytes.value) ||0 )* 100).toFixed(2)) }},watch:{percentage(){if(this.percentage == 100 && this.totalBytes.value != 0){ElMessage({message:"下载完成!",type:"success"})}},},methods: {limitFormat(limit) {var size = "";if (limit < 0.1 * 1024) { //小于0.1KB,则转化成Bsize = limit.toFixed(2) + "B"} else if (limit < 0.1 * 1024 * 1024) { //小于0.1MB,则转化成KBsize = (limit / 1024).toFixed(2) + "KB"} else if (limit < 0.1 * 1024 * 1024 * 1024) { //小于0.1GB,则转化成MBsize = (limit / (1024 * 1024)).toFixed(2) + "MB"} else { //其他转化成GBsize = (limit / (1024 * 1024 * 1024)).toFixed(2) + "GB"}var sizeStr = size + ""; //转成字符串var index = sizeStr.indexOf("."); //获取小数点处的索引var dou = sizeStr.substr(index + 1, 2) //获取小数点后两位的值if (dou == "00") { //判断后两位是否为00,如果是则删除00return sizeStr.substring(0, index) + sizeStr.substr(index + 3, 2)}return size;}},}
</script><style scoped>
.task-item {width: 280px;display: flex;align-items: center;margin-bottom: 6px;
}.progress1 {font-size: 12px;margin-top: -4px;color: #999;
}.task-item i {}.img {width: 32px;height: 32px;display: block;margin-right: 14px;}
</style>

download.js完整代码

const { ipcMain, dialog, shell } = require('electron')
const path = require('path')
const fs = require('fs');
const { type } = require('os');
exports.initDownload = function (win) {let filePath = '';// 监听渲染进程发出的download事件const webContents = win.webContents;ipcMain.on('download', (evt, args) => {const fileArr = args.split("/");let ext = path.extname(args)let filters = [{ name: '全部文件', extensions: ['*'] }]if (ext && ext !== '.') {filters.unshift({name: '',extensions: [ext.match(/[a-zA-Z]+$/)[0]]})}dialog.showSaveDialog(win, {filters,defaultPath:args}).then( res => {if(res.filePath){filePath = res.filePathwebContents.downloadURL(args) // 注意这里必须是下载文件可访问路径。而不是存储路径}})})webContents.session.on('will-download', (event, item, webContents) => {item.setSavePath(filePath) // 这里是存储路径或者存储文件名称var filName = path.basename(filePath)win.webContents.send('win-will-download',{type:'start',params:{filName}})item.on('updated', (event, state) => {if (state === 'interrupted') {console.log('Download is interrupted but can be resumed')} else if (state === 'progressing') {if (item.isPaused()) {console.log('Download is paused')} else {win.webContents.send('win-will-download',{type:"progress",params:{totalBytes:item.getTotalBytes(),receivedBytes:item.getReceivedBytes()}})}}})item.once('done', (event, state) => {if (state === 'completed') {win.webContents.send('win-will-download',{type:"completed"})console.log('Download successfully')} else {console.log(`Download failed: ${state}`)}})})
}

main.js中使用代码
这里的main.js是electron的主进程文件,不是vue相关的问题

const { BrowserWindow } = require("electron");
const {initDownload} = require('@/utils/download.js')
var win = null;
async function createWindow() {win = new BrowserWindow({// 创建相关的参数});// 为创建的win窗口绑定下载事件initDownload(win)
}
createWindow()

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com