vue
的electron
环境,更多配置请访问源项目npm i -g vue-cli
vue init simulatedgreg/electron-vue my-project
cd my-project
npm i
npm run dev
复制代码
electron
主进程与渲染进程的通讯定义常量做为
channel
,也就是事件类型名称javascript
const CLIENT_NORMAL_MSG = 'CLIENT_NORMAL_MSG' // 渲染进程发出消息类型
const CRAWLER_NORMAL_MSG = 'CRAWLER_NORMAL_MSG' // 主进程发出消息类型
复制代码
在渲染进程中,使用vue plugin
的形式,具体参见vue
官方文档插件css
ipcRenderer
是eventEmitter的一个实例,在渲染进程中使用,你能够经过它来像主进程发送同步和异步消息,也能够经过它来接收来自主进程的消息html
const { ipcRenderer } = require('electron')
const ipcService = Object.create(null)
const callbackCache = []
ipcService.install = Vue => {
Vue.prototype.$ipcRenderer = {
send: (msgType, msgData) => {
ipcRenderer.send(CLIENT_NORMAL_MSG, {
type: msgType,
data: msgData,
})
},
on: (type, callback) => {
callbackCache.push({
type,
callback,
})
}
}
ipcRenderer.on(CRAWLER_NORMAL_MSG, (sender, msg) => {
callbackCache.forEach(cache => {
if (cache.type === msg.type) {
cache.callback && cache.callback(msg.data)
}
})
}) // 监听主进程的消息
}
export default ipcService
复制代码
在vue
项目中经过this.$ipcRenderer.on
的方式添加主进程发送消息的监听,经过this.$ipcRenderer.send
的方式向主进程发送消息,保证发出消息均为CLIENT_NORMAL_MSG
类型,收到消息均为CRAWLER_NORMAL_MSG
,经过消息中的二级固定参数type
来区分具体类型,并能够经过detach
的方式来取消特定的类型的消息的监听vue
最后在Vue
的入口文件,也就是渲染进程的入口文件使用上面定义的插件 Vue.use(ipcService)
渲染进程中的配置完成java
使用class
的方式来定义,须要传入两个参数来实例化这个class
,须要传入两个参数,listener
为监听消息者,sender
为发送消息者node
ipcMsgHandler
中包含了全部的handler
,为其传入this
以便可以在其中向渲染进程发送消息ios
import ipcMsgHandler from './ipcMsgHandler'
export default class Ipc {
constructor(listener, sender) {
this.listener = listener
this.sender = sender
this.addListener(CLIENT_NORMAL_MSG, this.handleFn.bind(this))
this.handlerList = ipcMsgHandler(this)
}
handleFn(event, data) {
try {
this.handlerList[data.type](event, data.data)
} catch (error) {
console.error('handler event error:' + error.message)
}
}
addListener(chanel, cb) {
this.listener.on(chanel, cb)
}
_sendMsg(chanel, msgBody) {
this.sender.send(chanel, msgBody)
}
sendToClient(type, data) {
this._sendMsg(CRAWLER_NORMAL_MSG, {
type,
data,
})
}
}
复制代码
初始状态下ipcMsgHandler.js
文件git
export default _ipc => ({})
复制代码
在主进程的入口文件(/src/main/index.js
)中对Ipc
这个class
实例化,其中须要使用的listener
为ipcMain
,ipcMain
和ipcRenderer
不一样,它只负责对消息的监听,不复杂发送消息,这里须要入口文件中的mainWindow
下的webContents
做为消息的发送者,因此须要在mainWindow
建立成功以后再进行Ipc
的实例化github
// ...
function createWindow() {
mainWindow = new BrowserWindow({
// ...
});
new IpcMgr(ipcMain, mainWindow.webContents)
}
复制代码
element-ui
,使用babel
配置css
按需加载,具体配置方式element-ui官网掘金首页七种分类下数据均来自一个接口,https://timeline-merger-ms.juejin.im/v1/get_entry_by_rank?src=web&limit=20&category=xxx
,经过category
进行分类的区分web
在App.js
中,在进入页面和切换分类时向主进程发送消息
// ...
methods: {
startRequest() {
this.$ipcRenderer.send('start-request', this.activeCategory)
},
onRequestBack() {
this.$ipcRenderer.on('request-back', data => {
// todo...
})
},
}
复制代码
如今渲染进程中已经定义了两种消息类型start-request
和request-back
,start-request
告诉主进程开始执行任务,完成后request-back
告诉渲染进程任务完成,渲染进程收到消息后经过收到的数据来对页面进行操做。
在ipcMsgHandler.js
中进行拓展,使用axios
对接口内容进行抓取
import axios from 'axios'
const handlerList = _ipc => ({
['start-request'](event, category) {
const requestBack = data => {
_ipc.sendToClient('request-back', data)
}
axios.get(`https://timeline-merger-ms.juejin.im/v1/get_entry_by_rank?src=web&limit=20&category=${category}`)
.then(r => {
if(r.status === 200) {
requestBack({
success: true,
rows: r.data.d.entrylist
})
} else {
requestBack({
success: false,
error: `server error code: ${r.status}`
})
}
})
.catch(e => requestBack({
success: false,
error: `server error code: ${e.status} msg: ${e.message}`
}))
}
})
复制代码
请求完成后,经过requestBack
向渲染进程发送消息,渲染页面,操做样式调整,页面看起来大概是这样。
在该项目中若是直接使用window.open
的方式来打开的话,它会新弹出一个electron
窗口,全部链接跳转也须要用到ipc
的方式
在electron
中,有一个shell
对象,它提供一个openExternal
的方法来在默认浏览器中打开连接
在ipcMsgHandler.js
中新增如下内容
const { shell } = require('electron')
export default _ipc => ({
['open-shell'](event, url) {
shell.openExternal(url)
},
// ...
})
复制代码
如今就能够在vue
中经过this.$ipcRenderer.send('open-shell', url)
的方式来在默认浏览器中打开连接了
一个经过打通IPC
通讯方式的掘金首页概览客户端就完成了,经过npm run build
就能够对这个应用进行打包了
PS: 其实在electron
中是能够支持跨域访问的,只须要在建立窗口的时候加上一下配置项就好了,不过结果其实并不重要,重要的是过程了
webPreferences: {
webSecurity: false,
}
复制代码
以上代码均可以在github上找到,欢迎star~~~