本文介绍: 文章目录ElectronBuild开发问题浅解开机自启有关Webview有关webview用户登录webview调用ipcRenderer封装进程监听项目使用 PubSub防止多任务ElectronBuild打包问题浅解修改文件入口修改输出文件图标设置打包生成安装文件【前言】此文档是本人在实际开发中所遇到的问题,且已经解决的,因为技术有限,可能有很多地方,很多代码可能都还存在漏洞,如有疑问或者有更好解决方式,以及有代码可以优化的地方,欢迎留言,多谢大神指点。ElectronBuild开发问题浅解

【前言】此文档是本人在实际开发中所遇到的问题,且已经解决的,因为技术有限,可能有很多地方,很多代码可能都还存在漏洞,如有疑问或者有更好的解决方式,以及有代码可以优化的地方,欢迎留言,多谢大神指点。

ElectronBuild开发问题浅解

开机自启

之所以将这一项放在最前面,是因为这一点很重要,当需要进程执行app.setLoginItemSettings开机自启操作时,必须要将vue.config.js中的"requestedExecutionLevel": "highestAvailable",清除,否则将会导致app.setLoginItemSettings失效

至于为什么要在主进程监听中加入event.sender.send('setting-auto-start', true)看似在重复发送通信,是因为在Electron API文档中有提到,因此个人认为加上也无妨

/** 设置开机自启 **/
ipcMain.on('setting-auto-start', async (event, flag) => {
    if (flag) {
        app.setLoginItemSettings({
            openAtLogin: true,
            openAsHidden: true,
            path: process.execPath,
            args: [
                '--hideWindow', '"true"'
            ]
        })
        event.sender.send('setting-auto-start', true)
    } else {
        app.setLoginItemSettings({
            openAtLogin: false,
            openAsHidden: false,
            path: process.execPath,
            args: []
        })
        event.sender.send('setting-auto-start', false)
    }
})

有关Webview

使用webviewpreload时,需要注意的一点是preload需要传入的路径一个协议路径,比如file://http://等,而由于这里path.join获取的是编译后的路径,所以需要当前环境区分开来,当然也可以webview封装一个公共组件使用传值的方式加载相对应的srcpreload

<template>
    <webview class="webview" :src="weburl" :preload="filepath" :title="title" nodeintegrationinsubframes disablewebsecurity></webview>
</template>

<script>
    export default {
        props: ['weburl', 'filepath', 'title']
    }
</script>
if (process.env.NODE_ENV == 'production') {
    this.info.preloadUrl = path.join(__dirname, 'preload.js')
} else {
    this.info.preloadUrl = require('path').resolve('./src/utils/electron/preload.js')
}

Webview中常用监听方法属性

开发过程中,我们最有可能遇到的就是要对webview访客界面中的事件元素属性等进行操作。此时,我们可以通过使用webview.executeJavaScript()函数将JS注入到访客页面中,当然这些也仅仅只是针对于一些公共处理方法,如果有极个别的访客界面需要这些公共的操作,那就需要进行特殊处理

比如这里需要对访客界面的所有超链接标签进行监听点击链接客户端新建一个tab打开标签中的链接,而其中也针对访客页面中的iframe界面进行处理

const webview = document.querySelector('.webview')
//  在加载中添加监听
webview.addEventListener("did-start-loading", () => {
    webview.openDevTools()
    webview.executeJavaScript(`
        setTimeout(() => {
            if (document) {
                let nodeList = []
                let type = 'default'
                let tabContent = document.querySelectorAll('.el-tab-pane')
                if (tabContent &amp;&amp; tabContent.length) {
                    tabContent.forEach(item => {
                        if (item.firstChild.contentWindow) {
                            type = 'tdd'
                            nodeList = item.firstChild.contentWindow.document.querySelectorAll('body a')
                        }
                    })
                } else {
                    nodeList = document.querySelectorAll('body a')
                }
                nodeList.length &amp;&amp; nodeList.forEach(item => {
                    let attr_type = item.getAttribute('target')
                    if (attr_type != '_blank') return false
                    item.addEventListener('click', (event) => {
                        let info = {
                            title: type == 'tdd' ? '涂多多商城-' + event.srcElement.innerText : event.srcElement.innerText,
                            src: event.srcElement.href || event.srcElement.parentNode.href,
                            type: 'webview'
                        }
                        window.electron.send('ibi_href_click', info)
                    }, false)
                })
            }
        }, 1500)
    `)
})

有关webview用户登录

const electronStore = require('electron-store')
const electronCookie = new electronStore()
setTimeout(() => {
    if (electronCookie.get('userInfo')) {
        if (electronCookie.get('userInfo').access_token &amp;&amp; document) {
            document.cookie = 'token=' + electronCookie.get('userInfo').access_token
        }
    }
})

webview中调用ipcRenderer

当访客端需要客户端发送通信指令时,可以在预加载文件(preload.js)中将electron挂载window上,从而使访客端可以直接通过window操作ipcRenderer客户端发送通信,同时也可以在preload中设置相应的方法,以供访客端可以通过调用获取客户端数据信息

封装进程监听

在实际开发中,我们可能会经常操作主进程和渲染进程之间的相互通信,而通信越多写的代码就会越多,如果不对这些监听进行分类封装,久而久之会导致项目维护起来很痛苦,每次都要先去找到监听指令在哪,找到以后可能也并不知道这个指令是在操作下载还是用户退出,或者是链接跳转,因此,这里我个人是通过类的方式,将不同类型的通信处理区分开,这样就会一目了然,看网上有很多大佬都是通过js导入的方式,都是可以的

项目中使用 PubSub

如果在项目中使用 PubSub 你就会发现这里面有一个坑,就是当触发PubSub.publish发布消息时,实际上PubSub.subscribe可能会被多次订阅监听,因此,遇到这种问题是,应该取消订阅

//  发布消息
PubSub.publish('check-login')

//  订阅消息
PubSub.unsubscribe('check-login')
PubSub.subscribe('check-login', () => {
    ...
})

防止多任务

正常情况下,Electron允许打包后使用快捷方式开启多任务,而我们需求是只能开启一个客户端端,并且不影响托盘,可以使用一下参考:

if (win) {
    const isAppInstance  = app.requestSingleInstanceLock()
    //  当检测到开机多任务时,关闭当前进程
    if (!isAppInstance) {
        app.quit()
    } else {
        app.on('second-instance', (event, argv, workingDirectory, additionalData, ackCallback) => {
            if (win) {
                if (win.isMinimized()) win.restore()
                win.focus()
                win.show()
            }
        })
    }
    setTimeout(() => {
        //  托盘设置,因为只需要在Windows系统上设置,所以需要排除mac系统
        if (!$platform.is_mac()) {
            let iconImage;
            const iconUrl = process.env.NODE_ENV === "development" ? path.join(__dirname, '..', "./src/assets/favicon.ico") : path.join(__dirname, "favicon.ico")
            appTray = new Tray(nativeImage.createFromPath(iconUrl))

            appTray.setToolTip(process.env.VUE_APP_NAME)
            //  单击托盘展示窗口,仅针对Windows系统
            appTray.on('click', () => {
                win.isVisible() ? win.hide() : win.show()
            })

            const contextMenu = Menu.buildFromTemplate([
                {
                    label: '打开窗口',
                    click: () => {
                        win.show()
                    },
                },
                {
                    label: '退出',
                    click: () => {
                        process.platform === 'darwin' ? app.quit() : win.destroy()
                    },
                },
            ])

            // 设置上下文菜单
            appTray.setContextMenu(contextMenu)
        }
    }, 500)
}

ElectronBuild打包问题浅解

修改文件入口

一般情况下electron-build的打包入口默认background.js,但如果有需求修改入口文件的话需要在vue.config.js修改pluginOptions.electronBuilder.mainProcessFile配置

注意: 设置自定义入口文件以后,package.json中的入口文件不需要改变,还是设置 background.js 作为入口就好,否则在打包时程序报错找不到 background.js,原因是因为vue-cli-plugin-electron-builder在打包时,默认package.json 中寻找入口文件,而 vue-cli-plugin-electron-builder默认入口文件还是 background.js,具体可以到 node_modules 中的 vue-cli-plugin-electron-builder查看源码

module.exports = {
    pluginOptions: {
        electronBuilder: {
            builderOptions: {
                mainProcessFile: 'src/index.js' //  设置自定义入口文件
            }
        }
    }
}
{
    "name": "demo",
    "version": "1.0.0",
    "private": true,
    "description": "This is Desccript",
    "main": "background.js",
    "author": "Me",
    "scripts": {
        "build": "vue-cli-service build",
        "lint": "vue-cli-service lint",
        "electron:build": "vue-cli-service electron:build",
        "electron:serve": "vue-cli-service electron:serve",
        "postinstall": "electron-builder install-app-deps",
        "postuninstall": "electron-builder install-app-deps"
    }
}

修改输出文件

默认情况下electron-build打包好的文件都会生成dist_electron中,而在实际开发中,我们也可以通过pluginOptions.electronBuilder.builderOptions.outputDir自定义打包文件,就像Vue-CLIoutputDir那样

module.exports = {
    pluginOptions: {
        electronBuilder: {
            builderOptions: {
                "directories": {
                  "output": "dist"  // 设置自定义输出文件
                }
            }
        }
    }
}

图标设置

在打包项目是通常会遇到,明明图标是设置了的,打包后却没有生效,或者打包报错失败,是因为在打包时,Windows要求打包的ico文件的尺寸需要在256*256,同时ico文件不能直接有png图标格式文件修改后缀名得出,而是需要通过ico处理的网站得出

打包生成安装文件

众所周知,我们使用electron或者electron-bhild最终目的就是要将项目打包成各个系统可以安装,并使用的安装文件,而这些也可以在pluginOptions.electronBuilder.builderOptions中来客制化

module.exports = {
    pluginOptions: {
        electronBuilder: {
            nodeIntegration: true,
            enableRemoteModule: true,
            removeElectronJunk: false,
            mainProcessFile: 'src/index.js',
            builderOptions: {
                "appId": "com.example.app",
                "productName": process.env.VUE_APP_NAME,    //  项目名,也是生成的安装文件名,即    aDemo.exe
                "copyright": "Copyright © 2022",    //  版权信息
                "directories": {
                  "output": "dist"  //  输出文件路径
                },
                "win": {    //  win相关配置
                    "icon": "./public/favicon.ico", //  图标当前图标在根目录下,注意这里有两个坑
                    "target": [
                        {
                            "target": "nsis",   //  利用nsis制作安装程序
                            "arch": [
                                "ia32", //  32位
                                "x64",  //  64位
                            ]
                        }
                    ]
                },
                "dmg": {
                    "contents": [
                        {
                            "x": 410,
                            "y": 150,
                            "type": "link",
                            "path": "/Applications"
                        },
                        {
                            "x": 130,
                            "y": 150,
                            "type": "file"
                        }
                    ]
                },
                "mac": {
                    "icon": "./src/assets/images/icon.icns"
                },
                "linux": {
                    "icon": "./src/assets/images/icon.icns"
                }
            }
        }
    }
}

原文地址:https://blog.csdn.net/snail767/article/details/124711326

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。

如若转载,请注明出处:http://www.7code.cn/show_8501.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注