公司有个内部桌面软件是基于electron vue写的,前几天负责开发这个客户端的人离职,我就成了临时接档优化的人。作为写vue但第一次接触electron的人,花了几天时间浏览了一下electron、electron vue官方文档、客户端代码的整体架构,即便如此,在优化过程中还是遇到了很多麻烦,项目结束后,特此做了一下总结。
af92760c989ae45131f75efdf95297d9.jpg

为了节省开发成本和开发时间,会使用已有的web页面。但由于业务的差异,总需要在electron项目中对已有的web页面做有一些小小的改动,这时候就需要对webview网页注入一部分js、css来支撑这些小改动,达到既不影响web页面之前的业务逻辑,又可以被目前项目的业务所使用的目的。

(1) 向webview网页注入css

在webview dom-read阶段,通过insertCSS()注入新样式

mounted() {
    const webview = this.$refs.webview

    webview.addEventListener('dom-ready', (e) => {
      this.mInsertCSS()
    })
 }
mInsertCSS() {
      webview.insertCSS(`
        .customer-panel {
          display: relative;
        }
      `)
    },

(1) 向webview网页注入js

官网:https://www.electronjs.org/docs/api/webview-tag
通过preload属性注入js代码
A String that specifies a script that will be loaded before other scripts run in the guest page. 

preload属性能够在webview内所有脚本执行之前,先执行指定的脚本,该脚本的URL的协议必须是 file:asar:二者之一,因为在访客页中,它是通过“内部”的 require 去加载的

mounted() {
    const webview = this.$refs.webview

    let preloadFile
    if (process.env.NODE_ENV === 'production') {
      preloadFile = `file://${global.__static}/preload.js`
    } else {
      preloadFile = 'file://' + require('path').resolve('static/preload.js')
    }
    webview.setAttribute('preload', preloadFile)
 }

preload环境可以使用Node APi,是一个既能用Node API,又能访问DOM、BOM的特殊环境。这样一个环境可以让我们在引入的js代码中可以使用ipcRenderer && ipcRenderer.sendToHost(paramsJSON)向electron渲染进程发送信息(具体操作,可以看electron(一)-webview与其加载页面间的通信、渲染进程间的通信、渲染进程与主进程间的通信https://segmentfault.com/a/11...

通过executeJavaScript()方法,在webview页面中执行js代码,并且向electron渲染进程返回Promise
<webview>.executeJavaScript(code[, userGesture])
-code String
-userGesture Boolean (可选) - 默认为 false

Returns Promise<any> - A promise that resolves with the result of the executed code or is rejected if the result of the code is a rejected promise.

这个方法更多的意思是:执行某段JavaScript代码,并且返回Promise,preload属性注入js代码,executeJavaScript()更多的是执行某一段代码,例如执行在webview代码执行前通过preload注入的js方法,并且可以对返回做一定的操作

this.$refs.webview.executeJavaScript(`__webViewFunction.getPhoneNumberList()`).then(result => {
        this.phoneNumberList = result || []
        // 查询缓存
        if (this.checkAllInCache(this.phoneNumberList)) {
          // 所有需要查询电话号码都在缓存
          console.log('allCache' + this.phoneNumberList)
        }
      })

愉快的时光总是那么短暂,又到了说再见的时刻.....
0c2ae8ce850df95e8272e1500d1416fc.jpg


xxjiayy
12 声望2 粉丝

世界那么大,有机会要多去看看