主要通过 Electron 中 will-download 事件和主进程和渲染进程之间的通信,实时监听下载进度
main/index.js
mainWindow.webContents.session.on('will-download', (e, item) => {
//获取文件的总大小
const totalBytes = item.getTotalBytes();
//设置文件的保存路径,此时默认弹出的 save dialog 将被覆盖
const rootPath = app.getPath("userData") + "/channel";
const filePath = path.join(rootPath, item.getFilename());
item.setSavePath(filePath);
//获得下载链接
let url = item.getURL()
//监听下载过程,计算并设置进度条进度
item.on('updated', () => {
let process = item.getReceivedBytes() / totalBytes
process = Math.round(process * 100)
mainWindow.setProgressBar(process);
//向渲染进程发送下载进度
sendMessage(url, process)
});
//监听下载结束事件
item.on('done', (e, state) => {
//如果窗口还在的话,去掉进度条
if (!mainWindow.isDestroyed()) {
mainWindow.setProgressBar(-1);
}
//下载被取消或中断了
if (state == 'interrupted') {
electron.dialog.showErrorBox('下载失败', `文件 ${item.getFilename()} 因为某些原因被中断下载`);
}
if (state == 'completed') {
//下载完成向渲染进程发送完成信号
sendMessage(url + ':done', 'done')
}
});
});
//向渲染进程发送信息
function sendMessage(url, text) {
mainWindow.webContents.send(url, text);
}
渲染进程
<template>
<el-table :data="updateDatas">
<el-table-column property="name" label="应用名" width="100px"></el-table-column>
<el-table-column property="url" label="下载链接"></el-table-column>
<el-table-column align="center" width="140px">
<template slot="header">
状态
</template>
<template slot-scope="scope">
<a
:href="scope.row.url"
@click="startDownload(scope.row,scope.$index)"
v-if="!scope.row.progress"
>
<el-button size="mini" type="danger">下载</el-button>
</a>
<el-button size="mini" type="success" v-if="scope.row.progress==100">完成</el-button>
<div
class="progress-bar"
:style="'width:' +scope.row.progress+'%'"
v-if="scope.row.progress && scope.row.progress!=100"
></div>
</template>
</el-table-column>
</el-table>
</template>
<script>
import { ipcRenderer } from "electron";
const axios = require("axios");
export default {
data() {
return {
updateDatas: [],
downloadState: 0
};
},
methods: {
startDownload(row, index) {
this.downloadState += 1;
//监听下载进程
ipcRenderer.on(row.url, (event, progress) => {
if (progress) {
this.$set(this.updateDatas[index], "progress", progress);
}
});
ipcRenderer.on(row.url + ":done", (event, state) => {
if (state == "done") {
this.downloadState -= 1;
console.log(row.url + "done");
}
});
}
},
watch: {
downloadState: function() {
if (this.downloadState == 0) {
this.$message.success("全部下载完成,重新加载中,请稍等");
this.downloadUrlVisible = false;
this.$emit("refresh");
}
}
},
//生命周期 - 创建完成(访问当前this实例)
created() {
this.init();
},
//生命周期 - 挂载完成(访问DOM元素)
mounted() {}
};
</script>
<style scoped>
.progress {
margin-top: 2px;
width: 200px;
height: 14px;
margin-bottom: 10px;
overflow: hidden;
background-color: #f5f5f5;
border-radius: 4px;
-webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
}
.progress-bar {
background-color: rgb(92, 184, 92);
background-image: linear-gradient(
45deg,
rgba(255, 255, 255, 0.14902) 25%,
transparent 25%,
transparent 50%,
rgba(255, 255, 255, 0.14902) 50%,
rgba(255, 255, 255, 0.14902) 75%,
transparent 75%,
transparent
);
background-size: 40px 40px;
box-shadow: rgba(0, 0, 0, 0.14902) 0px -1px 0px 0px inset;
box-sizing: border-box;
color: rgb(255, 255, 255);
display: block;
float: left;
font-size: 12px;
height: 16px;
line-height: 20px;
text-align: center;
transition-delay: 0s;
transition-duration: 0.6s;
transition-property: width;
transition-timing-function: ease;
width: 266.188px;
}
</style>
实例
- 界面


