electron開發客戶端注意事項(兼開源我的知識管理工具「想學嗎」)

窗口間通訊的問題

electron窗口通訊比nwjs要麻煩的多html

electron分主進程和渲染進程,渲染進程又分主窗口的渲染進程和子窗口的渲染進程vue

主窗口的渲染進程給子窗口的渲染進程發消息react

subWin.webContents.on('dom-ready', () => {
    subWin.webContents.send('message', {
        title: self.$root.a[self.$root.aIndex].title,
        content: window.UE.instants.ueditorInstant0.getContent(),
        id: self.$root.a[self.$root.aIndex].id,
        winId: item.winId,
        siteId: item.id,
        url,
        type
    });
});

子窗口的渲染進程接收消息的代碼linux

ipcRenderer.on('message', (event, article) => {
    console.log(article);
})

注意,應該dom-ready了以後再發,要否則你的子窗口進程有可能接收不到消息git

 

子窗口的渲染進程給主窗口的渲染進程發消息比較麻煩github

子窗口要先把消息發送給主進程,再由主進程中轉給主窗口web

const { ipcRenderer} = require('electron');
ipcRenderer.send('articleRefreshMain', {
            siteId:'cnblogs',
            url: url
        });

主進程接收消息後中轉給主窗口渲染進程的代碼json

import { app, BrowserWindow,ipcMain } from 'electron'
ipcMain.on('articleRefreshMain', (event, message) => {
  mainWindow.webContents.send('contentRefreshRenderer', message);
});

主窗口渲染進程接收消息的代碼app

ipcRenderer.on('articleRefreshRenderer', (e, message) => {
    self.$root.a[self.$root.aIndex][message.siteId] = {
        url: message.url
    }
    self.$root.needSave.a = true;
});

監聽編輯器內圖片刪除的事件

經過黏貼或者拖拽進編輯器的圖片,我把它複製到了文章的目錄(用戶本地目錄)dom

若是用戶在編輯文章的過程當中,又刪了這個圖片,那麼我應該在目錄中也刪除這個圖片

這就須要監控文章編輯器的圖片變化

我用的是H5的MutationObserver對象,理論上,用這個東西能夠監控任何DOM的變化

var editorDocument = document.getElementById("ueditor_0").contentWindow.document;
var observer = new MutationObserver(records => {
    self.$root.needSave.c = true;
    records.forEach((item, index) => {
        if (item.removedNodes.length > 0 && item.removedNodes[0].tagName == "IMG") {
            var path = decodeURI(item.removedNodes[0].src.substr(7));
            fs.unlink(path, err => {
                if (err) console.log(err);
            });
        }
    });
});
observer.observe(editorDocument, {
    childList: true,
    subtree: true
});

electron-vue獲取app版本號的hack代碼

原本electron獲取app版本號很簡單,只要以下便可(如下代碼運行在main進程中)

import { app, BrowserWindow,ipcMain } from 'electron'
var versionStr = app.getVersion();

getVersion: 若是應用程序的 package. json 文件中找不到版本號, 則返回當前包或者可執行文件的版本(就是electron的版本號)。

由於我用的electron-vue,他又兩種模式,生產模式和開發模式

在生產模式下沒任何問題

在開發模式下,它實際上是起了一個webserver,讓electron加載一個localhost的地址

這樣作主要是爲了使用vue的hotload的優點

但這樣的話,electron就找不到 package. json 文件中的版本號了

怎麼辦呢?

咱們在應用啓動的時候,先在主進程中把版本號拿出來

if (process.env.NODE_ENV !== 'development') {
  global.__static = require('path').join(__dirname, '/static').replace(/\\/g, '\\\\')
  winURL = `file://${__dirname}/index.html`;
}else{
  app.getVersion = ()=> curVersion;
  winURL = `http://localhost:9080`;
}

注意,咱們經過app.getVersion = ()=> curVersion;把getVersion方法給hack了

把文章內容填入特殊的網站編輯器中

在處理文章提交到知乎的過程當中

發現知乎用了一個特殊的編輯器,

(一個基於reactjs的編輯器,github上有開源的,忘記地址了)

怎麼搞都搞不定,他甚至不支持設置HTML的內容

最後用了electron的操做剪切板的能力才搞定的

先把文章內容放到剪貼板,再focus知乎的編輯器,再執行黏貼事件

代碼以下:

const {
    clipboard,
    ipcRenderer,
    remote
} = require('electron');
        var win = remote.BrowserWindow.fromId(this.winId);
        win.focus();
        setTimeout(function () {
            document.getElementsByClassName("WriteIndex-titleInput")[0].children[0].focus();
            clipboard.writeText(this.title);
            win.webContents.paste();
            setTimeout(function () {
                document.getElementsByClassName("public-DraftEditor-content")[0].click();
                clipboard.writeHTML(this.doc.body.innerHTML);
                win.webContents.paste();
                ipcRenderer.send('articleRefreshMain', {
                    siteId: 'zhihu',
                    url: window.location.href
                });
            }.bind(this), 800)
        }.bind(this), 800)

注意,若是要黏貼兩個地方,最好間隔個幾百毫秒

要否則網頁還沒反應過來,你就focus另外一個地方了,會致使黏貼不成功。

開源說明

源碼地址:https://github.com/xland/xiangxuema(界面截屏也在這裏)

支持平臺:win x6四、mac x6四、linux x64(打包編譯腳本都在)

編譯好的應用程序,我放到了阿里雲的CDN裏,下載速度超讚,你們能夠下載來用用看

有什麼問題,請不吝提交issue,有issue必回!

相關文章
相關標籤/搜索