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~~~