zoukankan      html  css  js  c++  java
  • electronvue开发问题总结

    1.Electron 12中的remote模块已弃用,将在Electron 14中拆除.由@electronic/remote 模块替代

    npm install --save @electron/remote
    在主线程中使用:
    注意:主进程要进行如下设置
         webPreferences: {
                nodeIntegration: !process.env.ELECTRON_NODE_INTEGRATION, ///process.env.ELECTRON_NODE_INTEGRATION===false
                contextIsolation: process.env.ELECTRON_NODE_INTEGRATION,
                enableRemoteModule: !process.env.ELECTRON_NODE_INTEGRATION,
            }
    require(’@electron/remote/main’).initialize()// 开启。这个必须得有。否则也创建不了
    require("@electron/remote/main").enable(webContents)

        示例:

    'use strict'

    import {
        app,
        protocol,
        BrowserWindow,
        ipcMain,
        Menu,
        Tray
    } from 'electron'
    import {
        createProtocol
    } from 'vue-cli-plugin-electron-builder/lib'
    //import installExtension, { VUEJS_DEVTOOLS } from 'electron-devtools-installer'
    const isDevelopment = process.env.NODE_ENV !== 'production'
    const path = require('path');
    require('@electron/remote/main').initialize()


    // 在应用程序准备就绪之前,必须注册方案
    protocol.registerSchemesAsPrivileged([{
        scheme: 'app',
        privileges: {
            secure: true,
            standard: true
        }
    }])
    let mainWindow = null
    let tray = null /******* 创建系托盘 *******/
    let CreateTray =
        () => {
            tray = new Tray(path.join(__static, 'img/app.png'));
            const contextMenu = Menu.buildFromTemplate([{
                    label: '设置',
                    click: () => {} //打开相应页面
                },
                {
                    label: 'Item1',
                    type: 'radio'
                },
                {
                    label: 'Item2',
                    type: 'radio',
                    checked: true
                },
                {
                    label: '退出',
                    click: () => {
                        if (!!mainWindow) {
                            mainWindow.destroy()
                            mainWindow
                                = null
                        }
                        if (!!DesktopToolWindow) {
                            DesktopToolWindow.destroy()
                            DesktopToolWindow
                                = null
                        }
                    }
                }, //我们需要在这里有一个真正的退出(这里直接强制退出)
            ])
            tray.setToolTip('My托盘测试')
            tray.setContextMenu(contextMenu)
            tray.on('click', () => { //我们这里模拟桌面程序点击通知区图标实现打开关闭应用的功能
                console.log("mainWindow.isVisible(", mainWindow.isVisible()) //isMinimized()
                mainWindow.show()

            })

        }
    async function createWindow() {
        // 创建浏览器窗口。
        mainWindow = new BrowserWindow({
            710,
            height: 492,
            resizable: false,
            frame: false,
            transparent: false,
            webPreferences: {
                nodeIntegration: !process.env.ELECTRON_NODE_INTEGRATION, ///process.env.ELECTRON_NODE_INTEGRATION===false
                contextIsolation: process.env.ELECTRON_NODE_INTEGRATION,
                enableRemoteModule: !process.env.ELECTRON_NODE_INTEGRATION,
            }
        })
        mainWindow.setSkipTaskbar(false)
        mainWindow.flashFrame(true)

        console.log("process.env.WEBPACK_DEV_SERVER_URL", process.env.WEBPACK_DEV_SERVER_URL)
        if (process.env.WEBPACK_DEV_SERVER_URL) {
            // 如果处于开发模式,请加载开发服务器的url
            await mainWindow.loadURL(process.env.WEBPACK_DEV_SERVER_URL)
            if (!process.env.IS_TEST) mainWindow.webContents.openDevTools()
        } else {
            createProtocol('app')
                // 加载索引,非开发中的html
                //mainWindow.loadURL('app://./index.html')
            mainWindow.loadURL('app://./index.html')
        }
        mainWindow.once("ready-to-show", () => {
                mainWindow.show();
            })
            // mainWindow.setMenu(null)


        /******* 引入远程模块 *******/
        require("@electron/remote/main").enable(mainWindow.webContents);

        mainWindow.on('closed', (event) => {
            mainWindow = null;

        });

        // mainWindow.on('close', (event) => {
        //     event.preventDefault();

        // });
        // mainWindow.on('show', (event) => {
        //     event.preventDefault();

        // })
        // mainWindow.on('hide', (event) => {
        //         event.preventDefault();

        //     })
    }

    // 关闭所有窗口后退出。
    app.on('window-all-closed', () => {
        // 在macOS上,应用程序及其菜单栏很常见
        // 在用户使用Cmd+Q明确退出之前保持活动状态
        if (process.platform !== 'darwin') {
            app.quit()
        }
    })

    app.on('activate', () => {
        //在macOS上,当
        //已单击停靠图标,并且没有其他窗口打开。
        if (BrowserWindow.getAllWindows().length === 0) createWindow()
    })

    //此方法将在Electron完成后调用
    //初始化并准备好创建浏览器窗口。
    //某些API只能在此事件发生后使用。
    app.on('ready', async() => {
        if (isDevelopment && !process.env.IS_TEST) {
            // 安装视图开发工具
            try {
                //await installExtension(VUEJS_DEVTOOLS)
            } catch (e) {
                console.error('Vue Devtools failed to install:', e.toString())
            }
        }
        createWindow()

        /******* 创建系托盘 *******/
        CreateTray()
            /******* 监听渲染进程通信 *******/
        ipcMain.on('HomePage', (event, arg) => {
            console.log(arg)
            DesktopTool()
            mainWindow.resizable = true
            mainWindow.transparent = false
            mainWindow.minimize();
            event.reply('HomePage-reply', "我是主进程传过去的参数")
        })

        ipcMain.on('DesktopTool', (event, arg) => {
                console.log(arg)
                mainWindow.resizable = true
                mainWindow.transparent = false
                mainWindow.show();
                event.reply('DesktopTool-reply', "我是主进程传过去的参数")
            })
            //
        ipcMain.on('CloseClick', (event, arg) => {
            console.log(arg)
            mainWindow.resizable = true
            mainWindow.transparent = false
            mainWindow.minimize();
            event.reply('CloseClick-reply', "我是CloseClick-reply传过去的参数")
        })

    })

    // 在开发模式下,根据父进程的请求干净地退出。
    if (isDevelopment) {
        if (process.platform === 'win32') {
            process.on('message', (data) => {
                if (data === 'graceful-exit') {
                    app.quit()
                }
            })
        } else {
            process.on('SIGTERM', () => {
                app.quit()
            })
        }
    }

    /******* 以下是渲染进程 *******/ // 开启DesktopToolWindow新窗口
    let DesktopToolWindow = null

    function DesktopTool() {

        if (!!DesktopToolWindow) {
            DesktopToolWindow.show()
        } else {
            CreateDesktopToolWindow()
        }
    }

    async function CreateDesktopToolWindow() {
        DesktopToolWindow = new BrowserWindow({
            160,
            height: 160,
            parent: null,
            resizable: false,
            frame: false,
            transparent: true,
            alwaysOnTop: true,
            webPreferences: {
                nodeIntegration: !process.env.ELECTRON_NODE_INTEGRATION, ///process.env.ELECTRON_NODE_INTEGRATION===false
                contextIsolation: process.env.ELECTRON_NODE_INTEGRATION,
                enableRemoteModule: !process.env.ELECTRON_NODE_INTEGRATION,
            }
        })
        if (process.env.WEBPACK_DEV_SERVER_URL) {
            // 如果处于开发模式,请加载开发服务器的url
            await DesktopToolWindow.loadURL(process.env.WEBPACK_DEV_SERVER_URL + '#/ztdada/desktoptool')
                // if (!process.env.IS_TEST) //DesktopToolWindow.webContents.openDevTools()
        } else {
            createProtocol('app')
                // 加载索引,非开发中的html
            await DesktopToolWindow.loadURL('app://./index.html#/ztdada/desktoptool')
                //await DesktopToolWindow.loadURL("https://bilibili.com/")
        }

        // DesktopToolWindow.loadURL(process.env.WEBPACK_DEV_SERVER_URL + '#/ztdada/desktoptool');
        DesktopToolWindow.setIgnoreMouseEvents(false)
        DesktopToolWindow.setSkipTaskbar(true)
            // DesktopToolWindow.loadURL("https://bilibili.com/")
            //DesktopToolWindow.loadFile('../src/pages/DesktopToolPage/index.vue')
        DesktopToolWindow.on('closed', () => {
            DesktopToolWindow = null
        })



    }

    在渲染进程使用(.vue文件):

    注意:在vue文件中直接require("electron")会报错,需要这样引入

    const { require } = window;
    const { ipcRenderer } = require("electron");
    const { BrowserWindow } = require("@electron/remote");

    或者这样引入

    const { ipcRenderer } =  window.require("electron");
    const { BrowserWindow } =  window.require("@electron/remote");

        示例:

    <script>
    const { require } = window;
    const { ipcRenderer } = require("electron");
    const { BrowserWindow } = require("@electron/remote");
    export default {
      name: "HomePage",
      mounted() {
        ipcRenderer.on("HomePage-reply", (event, arg) => {
          console.log(arg);
        });
      },
      methods: {
        RenderClick() {
          ipcRenderer.send("HomePage", "我是子进程传过去的参数");
        },
      },
    };
    </script>

     2.@electron/remote经过上面配置在开发环境可以正常使用,但打包时,还需做以下配置,否则打包后运行软件会报错

    官网上是这样解释:

    本机模块受支持,并且应在不进行任何配置的情况下工作,前提是启用了节点集成。如果出现错误,可能需要将本机依赖项设置为外部网页包(打开新窗口)。应该会自动找到它,但可能不会。为此,请使用externals选项. 

    https://nklayman.github.io/vue-cli-plugin-electron-builder/guide/guide.html#table-of-contents

     externals: ['@electron/remote'],
     nodeModulesPath: ['../../node_modules', './node_modules'],

    在vue.config.js文件中:

      pluginOptions: {
            'style-resources-loader': {
                preProcessor: 'scss',
                patterns: [path.resolve(__dirname, './src/assets/globalscss/*.scss'), ]
            },
            electronBuilder: {
                externals: ['@electron/remote'],
                nodeModulesPath: ['../../node_modules', './node_modules'],
                builderOptions: {
                    productName: "volodya",
                    appId: 'volodya',
                    win: {
                        "target": [
                            "nsis"
                        ],
                        icon: 'src/assets/img/app.png',
                        "requestedExecutionLevel": "requireAdministrator",
                        'legalTrademarks': 'http://www.baidu.com/'
                    },
                    "nsis": {
                        "installerIcon": "src/assets/ico/app.ico",
                        "uninstallerIcon": "src/assets/ico/app.ico",
                        "uninstallDisplayName": "CPU Monitor",
                        "license": "src/assets/ico/license.html",
                        "oneClick": false,
                        "allowToChangeInstallationDirectory": true,
                        "displayLanguageSelector": true,
    
                    },
                    "mac": {
                        "icon": "src/assets/ico/app.icns", // 应用程序图标
                        "artifactName": "volodya", // 应用程序包名
                        "target": [
                            "dmg",
                            "zip"
                        ]
                    },
                    'dmg': {
                        'title': 'volodya',
                        'icon': 'src/assets/ico/app.icns',
                        'contents': [{
                                'x': 110,
                                'y': 150
                            },
                            {
                                'x': 240,
                                'y': 150,
                                'type': 'link',
                                'path': '/Applications'
                            }
                        ],
                        'window': {
                            'x': 400,
                            'y': 400
                        }
                    }
                },
            },
        },

     3.在创建windows系统托盘时,let tray = null要设置为全局变量,否则会被回收机制清除,导致系统托盘自动消失的问题。

    注意: __dirname=== dist_electron ,__static === public,例如:app.png图片在vue-cli4创建的vue项目的public/img

    文件下,在electron项目里使用 path.join(__static, 'img/app.png')

    示例:

    /******* 创建系托盘 *******/
    let tray = null 
    let CreateTray =
        () => {
            tray = new Tray(path.join(__static, 'img/app.png'));
            const contextMenu = Menu.buildFromTemplate([{
                    label: '设置',
                    click: () => {} //打开相应页面
                },
                {
                    label: 'Item1',
                    type: 'radio'
                },
                {
                    label: 'Item2',
                    type: 'radio',
                    checked: true
                },
                {
                    label: '退出',
                    click: () => {
                        if (!!mainWindow) {
                            mainWindow.destroy()
                            mainWindow
                                = null
                        }
                        if (!!DesktopToolWindow) {
                            DesktopToolWindow.destroy()
                            DesktopToolWindow
                                = null
                        }
                    }
                }, //我们需要在这里有一个真正的退出(这里直接强制退出)
            ])
            tray.setToolTip('My托盘测试')
            tray.setContextMenu(contextMenu)
            tray.on('click', () => { //我们这里模拟桌面程序点击通知区图标实现打开关闭应用的功能
                console.log("mainWindow.isVisible(", mainWindow.isVisible()) //isMinimized()
                mainWindow.show()
    
            })
    
        }

    调用:

    CreateTray()

     4.vue,router,electron结合使用

    注意:路由要用hash模式,不可用history模式

    router/index.js

    /**
     * Модуль роутера приложения
     */
    
    import Vue from 'vue';
    import VueRouter from 'vue-router';
    import initListners from './initListners';
    import listners from './listners';
    import Home from '@/views/Home/index'
    Vue.use(VueRouter)
    
    const routes = [
        /* {
            path: '/',
            redirect: '/ztdada/home',
        }, */
        {
            path: '/ztdada/login',
            name: 'Login',
            component: () =>
                import ('@/views/Login/index'),
            meta: {
                Title: "登录",
    
            }
    
        }, {
            path: '/',
            name: 'Home',
            component: Home,
            // component: () =>
            //     import ('@/views/Home/index'),
            meta: {
                Title: "首页",
    
            }
        }, {
            path: '/ztdada/desktoptool',
            name: 'DesktopTool',
            component: () =>
                import ('@/views/DesktopTool/index'),
            meta: {
                Title: "首页",
    
            }
        }, {
            path: '*',
            component: () =>
                import ('@/views/Error/index'),
            hidden: true
        }
    ];
    
    const router = new VueRouter({
        // mode: 'history',
        // base: process.env.BASE_URL,
        routes
    })
    
    export default initListners(router, listners);

    在electron项目中使用:

    background.js

    “/”根路径页面"http://192.168.252.1:8080/#/"使用

    if (process.env.WEBPACK_DEV_SERVER_URL) {
            // 如果处于开发模式,请加载开发服务器的url
            await mainWindow.loadURL(process.env.WEBPACK_DEV_SERVER_URL)
            if (!process.env.IS_TEST) mainWindow.webContents.openDevTools()
        } else {
            createProtocol('app')
                // 加载索引,非开发中的html
                //mainWindow.loadURL('app://./index.html')
            mainWindow.loadURL('app://./index.html')
        }

    路由页面"http://192.168.252.1:8080/#/ztdada/desktoptool"使用

     if (process.env.WEBPACK_DEV_SERVER_URL) {
            // 如果处于开发模式,请加载开发服务器的url
            await DesktopToolWindow.loadURL(process.env.WEBPACK_DEV_SERVER_URL + '#/ztdada/desktoptool')
                // if (!process.env.IS_TEST) //DesktopToolWindow.webContents.openDevTools()
        } else {
            createProtocol('app')
                // 加载索引,非开发中的html
            await DesktopToolWindow.loadURL('app://./index.html#/ztdada/desktoptool')
                //await DesktopToolWindow.loadURL("https://bilibili.com/")
        }

    示例:

    'use strict'
    
    import {
        app,
        protocol,
        BrowserWindow,
        ipcMain,
        Menu,
        Tray
    } from 'electron'
    import {
        createProtocol
    } from 'vue-cli-plugin-electron-builder/lib'
    //import installExtension, { VUEJS_DEVTOOLS } from 'electron-devtools-installer'
    const isDevelopment = process.env.NODE_ENV !== 'production'
    const path = require('path');
    require('@electron/remote/main').initialize()
    
    console.log(",__static, __dirname", __static, __dirname)
        // 在应用程序准备就绪之前,必须注册方案
    protocol.registerSchemesAsPrivileged([{
        scheme: 'app',
        privileges: {
            secure: true,
            standard: true
        }
    }])
    let mainWindow = null
    let tray = null /******* 创建系托盘 *******/
    let CreateTray =
        () => {
            tray = new Tray(path.join(__static, 'img/app.png'));
            const contextMenu = Menu.buildFromTemplate([{
                    label: '设置',
                    click: () => {} //打开相应页面
                },
                {
                    label: 'Item1',
                    type: 'radio'
                },
                {
                    label: 'Item2',
                    type: 'radio',
                    checked: true
                },
                {
                    label: '退出',
                    click: () => {
                        if (!!mainWindow) {
                            mainWindow.destroy()
                            mainWindow
                                = null
                        }
                        if (!!DesktopToolWindow) {
                            DesktopToolWindow.destroy()
                            DesktopToolWindow
                                = null
                        }
                    }
                }, //我们需要在这里有一个真正的退出(这里直接强制退出)
            ])
            tray.setToolTip('My托盘测试')
            tray.setContextMenu(contextMenu)
            tray.on('click', () => { //我们这里模拟桌面程序点击通知区图标实现打开关闭应用的功能
                console.log("mainWindow.isVisible(", mainWindow.isVisible()) //isMinimized()
                mainWindow.show()
    
            })
    
        }
    async function createWindow() {
        // 创建浏览器窗口。
        mainWindow = new BrowserWindow({
             710,
            height: 492,
            resizable: false,
            frame: false,
            transparent: false,
            webPreferences: {
                nodeIntegration: !process.env.ELECTRON_NODE_INTEGRATION, ///process.env.ELECTRON_NODE_INTEGRATION===false
                contextIsolation: process.env.ELECTRON_NODE_INTEGRATION,
                enableRemoteModule: !process.env.ELECTRON_NODE_INTEGRATION,
            }
        })
        mainWindow.setSkipTaskbar(false)
        mainWindow.flashFrame(true)
    
        console.log("process.env.WEBPACK_DEV_SERVER_URL", process.env.WEBPACK_DEV_SERVER_URL)
        if (process.env.WEBPACK_DEV_SERVER_URL) {
            // 如果处于开发模式,请加载开发服务器的url
            await mainWindow.loadURL(process.env.WEBPACK_DEV_SERVER_URL)
            if (!process.env.IS_TEST) mainWindow.webContents.openDevTools()
        } else {
            createProtocol('app')
                // 加载索引,非开发中的html
                //mainWindow.loadURL('app://./index.html')
            mainWindow.loadURL('app://./index.html')
        }
        mainWindow.once("ready-to-show", () => {
                mainWindow.show();
            })
            // mainWindow.setMenu(null)
    
    
        /******* 引入远程模块 *******/
        require("@electron/remote/main").enable(mainWindow.webContents);
    
    
    
    
    
        mainWindow.on('closed', (event) => {
            mainWindow = null;
    
        });
    
        // mainWindow.on('close', (event) => {
        //     event.preventDefault();
    
        // });
        // mainWindow.on('show', (event) => {
        //     event.preventDefault();
    
        // })
        // mainWindow.on('hide', (event) => {
        //         event.preventDefault();
    
        //     })
    }
    
    // 关闭所有窗口后退出。
    app.on('window-all-closed', () => {
        // 在macOS上,应用程序及其菜单栏很常见
        // 在用户使用Cmd+Q明确退出之前保持活动状态
        if (process.platform !== 'darwin') {
            app.quit()
        }
    })
    
    app.on('activate', () => {
        //在macOS上,当
        //已单击停靠图标,并且没有其他窗口打开。
        if (BrowserWindow.getAllWindows().length === 0) createWindow()
    })
    
    //此方法将在Electron完成后调用
    //初始化并准备好创建浏览器窗口。
    //某些API只能在此事件发生后使用。
    app.on('ready', async() => {
        if (isDevelopment && !process.env.IS_TEST) {
            // 安装视图开发工具
            try {
                //await installExtension(VUEJS_DEVTOOLS)
            } catch (e) {
                console.error('Vue Devtools failed to install:', e.toString())
            }
        }
        createWindow()
    
        /******* 创建系托盘 *******/
        CreateTray()
            /******* 监听渲染进程通信 *******/
        ipcMain.on('HomePage', (event, arg) => {
            console.log(arg)
            DesktopTool()
            mainWindow.resizable = true
            mainWindow.transparent = false
            mainWindow.minimize();
            event.reply('HomePage-reply', "我是主进程传过去的参数")
        })
    
        ipcMain.on('DesktopTool', (event, arg) => {
                console.log(arg)
                mainWindow.resizable = true
                mainWindow.transparent = false
                mainWindow.show();
                event.reply('DesktopTool-reply', "我是主进程传过去的参数")
            })
            //
        ipcMain.on('CloseClick', (event, arg) => {
            console.log(arg)
            mainWindow.resizable = true
            mainWindow.transparent = false
            mainWindow.minimize();
            event.reply('CloseClick-reply', "我是CloseClick-reply传过去的参数")
        })
    
    })
    
    // 在开发模式下,根据父进程的请求干净地退出。
    if (isDevelopment) {
        if (process.platform === 'win32') {
            process.on('message', (data) => {
                if (data === 'graceful-exit') {
                    app.quit()
                }
            })
        } else {
            process.on('SIGTERM', () => {
                app.quit()
            })
        }
    }
    
    /******* 以下是渲染进程 *******/ // 开启DesktopToolWindow新窗口
    let DesktopToolWindow = null
    
    function DesktopTool() {
    
        if (!!DesktopToolWindow) {
            DesktopToolWindow.show()
        } else {
            CreateDesktopToolWindow()
        }
    }
    
    async function CreateDesktopToolWindow() {
        DesktopToolWindow = new BrowserWindow({
             160,
            height: 160,
            parent: null,
            resizable: false,
            frame: false,
            transparent: true,
            alwaysOnTop: true,
            webPreferences: {
                nodeIntegration: !process.env.ELECTRON_NODE_INTEGRATION, ///process.env.ELECTRON_NODE_INTEGRATION===false
                contextIsolation: process.env.ELECTRON_NODE_INTEGRATION,
                enableRemoteModule: !process.env.ELECTRON_NODE_INTEGRATION,
            }
        })
        if (process.env.WEBPACK_DEV_SERVER_URL) {
            // 如果处于开发模式,请加载开发服务器的url
            await DesktopToolWindow.loadURL(process.env.WEBPACK_DEV_SERVER_URL + '#/ztdada/desktoptool')
                // if (!process.env.IS_TEST) //DesktopToolWindow.webContents.openDevTools()
        } else {
            createProtocol('app')
                // 加载索引,非开发中的html
            await DesktopToolWindow.loadURL('app://./index.html#/ztdada/desktoptool')
                //await DesktopToolWindow.loadURL("https://bilibili.com/")
        }
    
        // DesktopToolWindow.loadURL(process.env.WEBPACK_DEV_SERVER_URL + '#/ztdada/desktoptool');
        DesktopToolWindow.setIgnoreMouseEvents(false)
        DesktopToolWindow.setSkipTaskbar(true)
            // DesktopToolWindow.loadURL("https://bilibili.com/")
            //DesktopToolWindow.loadFile('../src/pages/DesktopToolPage/index.vue')
        DesktopToolWindow.on('closed', () => {
            DesktopToolWindow = null
        })
    
    
    
    }
    生产环境中electron加载路由页面
  • 相关阅读:
    PHP中使用CURL实现Get和Post请求方法
    编码规范
    session跨域共享问题解决方案
    第二十七节 新增语义标签
    第二十六节 屏幕适配之rem单位
    第二十五节 屏幕适配之em单位
    第二十四节 屏幕适配之响应式布局
    第二十三节 屏幕适配之流体布局
    第二十二节 屏幕适配之适配布局类型
    第二十一节 屏幕适配之背景图尺寸的设置
  • 原文地址:https://www.cnblogs.com/volodya/p/15788782.html
Copyright © 2011-2022 走看看