一,主进程和渲染进程之间的传参
1,主进程向渲染进程传参和接收参数
import { BrowserWindow, ipcMain } from 'electron'
mainWindow = new BrowserWindow({
// ...
})
// 主动发送给渲染进程
function sendMessage(code, data) {
mainWindow.webContents.send('new-message', { code, data })
}
// 接收渲染进程发过来的消息
ipcMain.on('new-message', function(event, arg) {
console.log('渲染线程发过来的消息:', arg)
switch (arg.code) {
case 'ping':
sendMessage('reply', {})
//发送给渲染进程也可以这样做
// event.sender.send('new-message', {code: 'reply', {}})
break;
}
})
2,渲染进程向主进程传参和接收主进程的传参
import { ipcRenderer } from 'electron'
export default {
mounted: function () {
ipcRenderer.on('new-message', function(e, data) {
console.log('主进程发过来的消息:', e, data)
switch(data.code) {
case 'reply':
// 逻辑
break;
}
})
},
methods: {
clickBtn(){
ipcRenderer.send('new-message', {code:'ping',data:{}}) // 发送给主线程
}
}
}
二,缩小,放大,关闭,全屏按钮的替换
系统默认的三个按钮样式不好看,不是我们想要的,故禁止显示默认后自己用样式写了一个来实现他们对应的功能。
1,先隐藏默认的系统菜单。
import { BrowserWindow, ipcMain } from 'electron'
mainWindow = new BrowserWindow({
height: 640,
width: 960,
useContentSize: true,
frame: false, // 隐藏默认的系统菜单
})
2,页面布局按钮样式,添加事件传给主进程告知做对应的放大缩小等操作。
<template>
<div class="menu-tool">
<div class="win-control">
<ul class="control-ul">
<li class="control-li" key="0" @click="clickWinBtn('shrink')">
<i class="iconfont"></i>
</li>
<li class="control-li" key="1" @click="clickWinBtn('magnify')" v-show="!showfullIcon">
<i class="iconfont"></i>
</li>
<li class="control-li" key="2" @click="clickWinBtn('full')" v-show="showfullIcon">
<i class="iconfont"></i>
</li>
<li class="control-li" key="3" @click="clickWinBtn('close')">
<i class="iconfont"></i>
</li>
</ul>
</div>
</div>
</template>
<script>
import { ipcRenderer } from 'electron'
export default {
props: {
},
components: {
},
data: function () {
return {
showfullIcon: false // 显示全屏的按钮
}
},
computed: {
},
mounted: function () {
ipcRenderer.on('new-message', (event, { code, data }) => {
switch (code) {
case 'show-full-icon':
this.showfullIcon = true
break;
case 'hide-full-icon':
this.showfullIcon = false
break;
}
})
},
methods: {
clickWinBtn(string) {
ipcRenderer.send('new-message', {code:string})
}
}
}
</script>
3,主进程收到渲染进程的事件控制窗口
function sendMessage(code, data) {
mainWindow.webContents.send('new-message', { code, data })
}
ipcMain.on('new-message', function(event, arg) {
switch (arg.code) {
case 'shrink':
// 缩小
mainWindow.minimize()
break;
case 'magnify':
// 放大
mainWindow.maximize()
sendMessage('show-full-icon')
break;
case 'close':
// 关闭
mainWindow.hide()
break;
case 'full':
// 退出全屏
mainWindow.unmaximize()
sendMessage('hide-full-icon')
break;
}
})
三,注册系统快捷键功能
我们按Ctrl+F12打开调试工具
import {globalShortcut } from 'electron'
globalShortcut.register('CommandOrControl+F12', () => {
mainWindow.webContents.openDevTools()
})
四,在电脑任务栏右下角显示托盘小图标,并让他能实现消息提醒闪烁的功能。
1,先禁止点击窗口关闭按钮时退出了APP。
import { app, BrowserWindow } from 'electron'
let mainWindow, quit = false
mainWindow = new BrowserWindow({
//...
})
//关闭窗口
mainWindow.on('close', (event) => {
mainWindow.hide()
mainWindow.setSkipTaskbar(true) // 任务栏不显示窗口
if (!quit) event.preventDefault() // 阻止默认事件退出APP
})
// 退出app
function quitApp() {
quit = true
app.quit()
}
2,显示托盘并给它鼠标右键的菜单,和点击托盘显示
import { Tray, Menu } from 'electron'
import path from 'path'
let appIcon = null
function tray() {
appIcon = new Tray(path.join(__static, 'icon.ico'))
let contextMenu = Menu.buildFromTemplate([{
label: '打开 APP',
click: function(e) {
mainWindow.show()
mainWindow.setSkipTaskbar(false)
}
},{
label: '退出 APP',
click: function(e) {
quitApp()
}
}]);
appIcon.setToolTip('APP名称');
appIcon.setContextMenu(contextMenu)
appIcon.on('click', function() {
mainWindow.show()
mainWindow.setSkipTaskbar(false)
})
}
3,加闪烁功能。
3 - 1,渲染进程页面上写两个按钮,控制托盘图标的闪烁
<template>
<div class="page-main">
<button key="1" @click="openFlicker">闪烁图标</button>
<button key="2" @click="closeFlicker">暂停闪烁</button>
</div>
</template>
<script>
import { ipcRenderer } from 'electron'
export default {
data: function () {
return {
}
},
computed: {
},
mounted: function () {
},
methods: {
openFlicker() {
ipcRenderer.send('open-flicker')
},
closeFlicker() {
ipcRenderer.send('close-flicker')
}
}
}
</script>
<style lang="scss" scoped>
</style>
3 - 2,主进程控制托盘小图标。思路是控制两张图片的交替显示,一张可以是透明的图片,从而起到闪烁效果。
import path from 'path'
let timer = null
ipcMain.on('open-flicker', function(event, arg) {
if (timer) return
let count = 0
timer = setInterval(function() {
count++
if (count % 2 === 0) {
appIcon.setImage(path.join(__static, 'icon.ico'))
} else {
appIcon.setImage(path.join(__static, 'favicon.ico'))
}
}, 500)
})
ipcMain.on('close-flicker', function(event, arg) {
clearInterval(timer)
timer = null
appIcon.setImage(path.join(__static, 'icon.ico'))
})
五,下载文件或打开文件以系统默认的打开方式。
文档连接https://www.electronjs.org/docs/api/download-item。
1,页面上加个打开文件的事件
openFile(url) {
ipcRenderer.send('new-message', {
code:'load-and-look',
data:{
filePath: url // 'www.网址/office.docx'
}
})
}
2,主进程收到文件的网络路径后先判断本地是否有改文件,有的话打开,没有的话下载后再打开。
import {app, session, shell } from 'electron'
import fs from 'fs'
// 发送给渲染进程
function sendMessage(code, data) {
mainWindow.webContents.send('new-message', { code, data })
}
// 接收渲染进程发过来的消息
ipcMain.on('new-message', function(event, arg) {
switch (arg.code) {
case 'load-and-look':
loadFile(arg.data)
break;
}
})
// 下载文件 和查看文件
let savePath = app.getPath('downloads') // 保存的路径,自定义
function loadFile(file) {
let pathList = file.filePath.split('/')
let fileName = pathList[pathList.length - 1]
fs.exists(`${savePath}\\${fileName}`,(exists)=> {
console.log(exists)
if (exists) {
shell.openItem(`${savePath}\\${fileName}`)
}else {
mainWindow.webContents.downloadURL(file.filePath)
}
})
}
// 监听下载
session.defaultSession.on('will-download', (event, item, webContents) => {
//设置文件存放位置
item.setSavePath(`${savePath}\\${item.getFilename()}`);
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('下载暂停')
} else {
let loadRate = item.getReceivedBytes() / item.getTotalBytes()
mainWindow.webContents.send('load-rate', { data: loadRate })
// console.log(`已经取回的字节: ${item.getReceivedBytes()}`)
}
}
})
item.once('done', (event, state) => {
if (state === 'completed') {
console.log('下载成功')
shell.openItem(`${savePath}\\${item.getFilename()}`)
} else {
console.log(`下载失败: ${state}`)
}
})
})