渲染进程加载Electron 方式1 浏览器端无法加载electron,那么,我们可以使用preload预加载将需要的接口暴露出来。
创建一个preload.js文件,放在入口文件main.js的同级目录下。
1 2 3 global .electron = require ('electron' );window .ipcRenderer = require ('electron' ).ipcRenderer ;window .remote = require ('electron' ).remote ;
修改main.js文件 在入口文件中添加preload配置项,将preload.js作为预加载文件。预加载的时候还是可以使用nodejs里的api
1 2 3 4 5 6 7 8 mainWindow = new BrowserWindow ({ width : 800 , height : 600 , webPreferences : { nodeIntegration : false , preload : __dirname + '/preload.js' } });
在组件中如下使用即可。
1 2 3 4 5 6 7 const electron = window .electron ;const remote = window .remote ;console .log (electron)console .log (remote.dialog )const {dialog} = window .remote ;dialog.showErrorBox ('title' , 'content' );
方式2 1 2 const { app, dialog } = window .require ("electron" ).remote ;const electron = window .require ('electron' );
主进程和渲染进程数据共享 主进程
1 2 3 global .sharedObject = { show_tongji : 0 }
设置值
1 global .sharedObject .show_tongji = 1 ;
取值
1 let show_tongji = global .sharedObject .show_tongji ;
渲染进程
1 2 3 const remote = window .require ('electron' ).remote ;remote.getGlobal ('sharedObject' ).show_tongji = 1 ;
取值
1 let show_tongji = remote.getGlobal ('sharedObject' ).show_tongji ;
赋值
1 remote.getGlobal ('sharedObject' ).show_tongji = 1 ;
基本配置 区分开发和生产环境 1 const isDevelopment = !app.isPackaged ;
高DPI支持 1 2 3 4 if (process.platform === 'win32' ) { app.commandLine .appendSwitch ('high-dpi-support' , 'true' ) app.commandLine .appendSwitch ('force-device-scale-factor' , '1' ) }
禁用硬件加速
非常重要 在一些集成显卡的电脑上,默认开启的硬件加速会导致应用看不到界面。
关闭硬件加速
1 app.disableHardwareAcceleration ()
webview HTML
1 2 3 4 <webview :src ="url" id ="myweb" class ="myweb" disablewebsecurity > </webview >
JS
1 2 3 4 5 6 7 8 9 10 11 let isreload = false ;this .url = url;this .$nextTick(() => { const webview = document .querySelector ('#myweb' ) webview.addEventListener ('dom-ready' , () => { if (!isreload) { webview.reloadIgnoringCache () isreload = true } }) })
CSS
1 2 3 4 5 .myweb { width : 100% ; height : 100% ; display : flex; }
初始化Win
1 2 3 4 5 6 7 8 9 10 11 new BrowserWindow ({ width : 1130 , height : 650 , transparent : false , webPreferences : { nodeIntegration : true , enableRemoteModule : true , webSecurity : false , contextIsolation : false , webviewTag : true })
注意
窗口初始化要开启webviewTag
样式display: flex;保证内部充满
webview调用其方法要等页面dom-ready
窗口 窗口透明 1 2 3 4 5 6 7 const { BrowserWindow } = require ('electron' );const win = new BrowserWindow ({ transparent : true , frame : false , backgroundColor : '#00000000' }); win.show ();
注意
frame设置为false是为了用无边窗口
transparent设置为true是使用窗口的透明效果
backgroundColor为一个透明的颜色,是因为BrowserWindow默认的背景颜色是白色,设置透明之后,才能够真正地看到透明的效果。
如果这个属性不设置会导致在有的电脑上是透明的有的不是,必须要设置。
系统配置
如果发现经过上述设置之后,窗口仍然不能透明的话,可能和Windows的设置有关 在Win7下,需要开启aero功能,在Win10下,需要开启颜色->透明效果
不显示菜单栏 1 2 3 4 5 const electron = require ('electron' )const Menu = electron.Menu Menu .setApplicationMenu (null )
窗口状态 1 2 3 4 5 6 const { BrowserWindow } = require ('electron' );const win = new BrowserWindow ();win.setProgressBar (0.5 ); let win = new BrowserWindow ()win.once ('focus' , () => win.flashFrame (false )) win.flashFrame (true )
窗口显示和隐藏 窗口显示
1 2 3 4 5 6 7 8 9 10 11 12 13 if (win && !win.isDestroyed ()) { if (win.isMinimized ()) { win.restore () } if (!win.isVisible ()) { win.show () } win.focus (); } else { }
窗口隐藏
1 2 3 if (win && !win.isDestroyed ()) { win.hide (); }
窗口托栏图标闪烁
窗口位置 1 2 3 4 5 6 7 8 const win = window .require ("electron" ).remote .getCurrentWindow ();const {screen} = window .require ("electron" ).remote ;let display = screen.getPrimaryDisplay ();let x = display.bounds .width - 80 ;let y = display.bounds .height - 630 - 44 ;win.setSize (76 , 630 ) win.setPosition (x, y)
窗口居中
窗口大小
1 2 win.setContentSize (160 , 120 ); win.setSize (160 , 120 );
注意
如果设置窗口变小 直接调用setSize是不生效的,要调用setContentSize修改内部尺寸才能改变窗口大小。
获取窗口句柄 1 2 3 4 const win = window .require ("electron" ).remote .getCurrentWindow ();let hwnd = win.getNativeWindowHandle ();let winId = hwnd.readUInt32LE (0 );console .info ("winId" , winId);
禁用右键菜单 1 2 3 4 5 6 7 8 9 10 function preventDragbarContext (win ) { var WM_INITMENU = 0x116 ; win.hookWindowMessage (WM_INITMENU , function (e ) { win.setEnabled (false ); setTimeout (() => { win.setEnabled (true ); }, 100 ); return true ; }) }
标题栏或者设置css的 -webkit-app-region: drag;的元素,当接收到右键的时候进行拦截,先设置窗口禁用,然后定时恢复。
特殊处理 1 2 app.disableDomainBlockingFor3DAPIs (); app.disableHardwareAcceleration ();
最大化最小化/显示隐藏/获得焦点 API
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 const win = window .require ("electron" ).remote .getCurrentWindow ();win.isMaximized () win.maximize () win.unmaximize () win.isMinimized () win.minimize () win.restore () win.isFocused () win.focus () win.blur ()
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 if (win && !win.isDestroyed ()) { if (win.isMinimized ()) { win.restore () } if (!win.isVisible ()) { win.show () } if (!win.isFocused ()) { win.focus () } } else { createFun () }
双击最大化问题 Electron无边框模式下-webkit-app-region: drag;双击最大化的问题 废话不多说 使用以下api即可解决:
1 2 3 4 5 mainWindow.setMenu (null ); mainWindow.setMaximizable (false ); mainWindow.setResizable (false );
或者创建窗口设置属性
1 2 maximizable: false , minimizable: false ,
防止窗口加载闪烁 1 2 3 4 5 const { BrowserWindow } = require ('electron' )const win = new BrowserWindow ({ show : false })win.once ('ready-to-show' , () => { win.show () })
防止透明窗口显示闪烁 main.js中添加
1 app.commandLine .appendSwitch ('wm-window-animations-disabled' );
创建无边框窗口 1 2 3 const { BrowserWindow } = require ('electron' )const win = new BrowserWindow ({ width : 800 , height : 600 , frame : false })win.show ()
禁止缩放 1 2 3 new BrowserWindow ({ resizable : false })
事件穿透 点击穿透窗口 1 2 3 const { BrowserWindow } = require ('electron' )const win = new BrowserWindow ()win.setIgnoreMouseEvents (true )
转发 忽略鼠标消息会使网页无视鼠标移动,这意味着鼠标移动事件不会被发出。 在 Windows 操作系统上,可以使用可选参数将鼠标移动消息转发到网页,从而允许发出诸如 mouseleave 之类的事件:
1 2 3 4 5 6 7 8 const win = require ('electron' ).remote .getCurrentWindow ()const el = document .getElementById ('clickThroughElement' )el.addEventListener ('mouseenter' , () => { win.setIgnoreMouseEvents (true , { forward : true }) }) el.addEventListener ('mouseleave' , () => { win.setIgnoreMouseEvents (false ) })
这将使网页在 el 上点击时穿透,在它外面时恢复正常。
渲染进程关闭窗口 1 2 3 const remote = require ('electron' ).remote ;const win = remote.getCurrentWindow ();win.close ();
应用关闭
1 2 const {app} = require ('electron' ).remote ;app.close ();
窗口 不在任务栏显示 1 homeWin.setSkipTaskbar (true )
true 表示不显示,false 表示显示。
获取焦点闪烁 1 2 win.once ('focus' , () => win.flashFrame (false )) win.flashFrame (true )
注意
别忘了调用 win.flashFramework(false) 来关闭闪烁。 在上面的示例中, 当窗口进入焦点时会调用它, 但您可能会使用超时或其他一些事件来禁用它。
点击任务栏不隐藏 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 let homeWin = new BrowserWindow ({ width : 1280 , height : 768 , fullscreen : true , simpleFullscreen : true , minimizable : false , frame : false , resizable : false , transparent : true , webPreferences : { nodeIntegration : true , enableRemoteModule : true , webSecurity : false , contextIsolation : false , }, }); homeWin.setFullScreen (true ); homeWin.setAlwaysOnTop (true , "pop-up-menu" );
只设置simpleFullscreen: true,和homeWin.setAlwaysOnTop(true, "pop-up-menu");的话,虽然窗口全屏了,但是一点击任务栏上的图标,界面就隐藏了,所以一定要添加上
1 homeWin.setFullScreen (true );
可能你会说直接隐藏任务栏图标不就行了
1 homeWin.setSkipTaskbar (true )
但是这样配置会导致任务栏会遮挡窗口,就算设置窗口置顶也没用,暂时没找到解决方法。
可拖拽和不可拖拽 1 2 3 4 5 6 7 body { -webkit-app-region: drag; } button { -webkit-app-region: no-drag; }
常用方式
如果窗口设置的可拖拽,那么按钮或需要触发点击的就取消拖拽,否则事件无法触发。
禁用文本选择 1 2 3 4 .titlebar { -webkit-user-select : none; -webkit-app-region: drag; }
自定义滚动条 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ::-webkit-scrollbar { width : 10px ; height : 1px ; } ::-webkit-scrollbar-thumb { border-radius : 10px ; -webkit-box-shadow : inset 0 0 5px #960200 ; background : #960200 ; } ::-webkit-scrollbar-track { -webkit-box-shadow : inset 0 0 5px #EDEDED ; border-radius : 10px ; background : #EDEDED ; }
设置checkbox选中背景色 1 <input type ="checkbox" id ="remeberpwd" /> <label for ="remeberpwd" > 记住密码</label >
样式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 input [type=checkbox] { cursor : pointer; position : relative; width : 15px ; height : 15px ; font-size : 14px ; border-radius : 4px ; } input [type=checkbox] ::after { position : absolute; top : 0 ; color : #ffffff ; width : 15px ; height : 15px ; display : inline-block; visibility : visible; padding-left : 0 ; text-align : center; content : ' ' ; border-radius : 3px } input [type=checkbox] :checked ::after { content : "✓" ; font-size : 12px ; background-color : #33C5B3 ; border-radius : 2px ; }
禁止图片拖动 1 2 3 img { -webkit-user-drag: none; }
禁用Console警告信息 cross-env 是一款跨平台设置和使用环境变量的脚本
1 npm install --save-dev cross-env
禁用
1 cross-env ELECTRON_DISABLE_SECURITY_WARNINGS=true
比如原来我的启动命令为
1 2 3 "scripts" : { "start" : "webpack --mode development && electron ." , }
就改为
1 2 3 "scripts" : { "start" : "webpack --mode development && cross-env ELECTRON_DISABLE_SECURITY_WARNINGS=true electron ." , }
隐藏掉这些警告信息,仅仅是个掩耳盗铃的行为,并不值得推荐使用。一定要看看警告是否能解决,不能解决又有强迫症的可以这样做。
安装本地Dev-Tools插件
官方文档:https://www.electronjs.org/docs/api/browser-window#browserwindowadddevtoolsextensionpath-deprecated
插件下载地址
链接:https://pan.baidu.com/s/19BzaBnZsWZxN_thHHvSYBw 提取码:psvm
Electron不同版本的API不一样
早期版本
1 2 3 4 5 6 7 const isDevelopment = !app.isPackaged ;app.whenReady ().then (() => { if (isDevelopment && !process.env .IS_TEST ) { BrowserWindow .addDevToolsExtension (path.resolve (__dirname, "./vue-devtools" )) } createWindow (); });
新版本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 const isDevelopment = !app.isPackaged ;app.whenReady ().then (() => { if (isDevelopment && !process.env .IS_TEST ) { try { const {session} = require ("electron" ); const path = require ("path" ); session.defaultSession .loadExtension ( path.resolve (__dirname, "./vue-devtools" ) ); } catch (e) { console .error ("Vue Devtools failed to install:" , e.toString ()); } } createWindow (); });
打开devtools
1 mainWindow.webContents .openDevTools ();
默认状态下,开发者工具的位置是上一次工具打开的位置(左边,右边,下边都有可能。取决于上一次的状态,但不会是分离状态,也没有处于顶部的状态)。
界面右侧打开
1 mainWindow.webContents .openDevTools ({mode :'right' });
界面底部打开
1 mainWindow.webContents .openDevTools ({mode :'bottom' });
界面左侧打开
1 mainWindow.webContents .openDevTools ({mode :'left' });
分离状态打开
1 mainWindow.webContents .openDevTools ({mode :'detach' });
DIV可拖动 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 drag_user_camera ( ) { let that = this ; let user_camera = this .$refs ["user_camera" ]; let camera_outer = this .$refs ["camera_outer" ]; camera_outer.addEventListener ('mousedown' , mouseDown, false ); document .addEventListener ('mouseup' , mouseUp, false ); function mouseDown ( ) { document .addEventListener ('mousemove' , sliderMove, false ); } function mouseUp ( ) { document .removeEventListener ('mousemove' , sliderMove, false ); if (that.camera_big ) { return } let myleft = parseInt (user_camera.style .left ); let mytop = parseInt (user_camera.style .top ); if (mytop < 0 ) { mytop = 0 ; } if (mytop + user_camera.clientHeight > document .body .clientHeight ) { mytop = document .body .clientHeight - user_camera.clientHeight ; } if (myleft < user_camera.clientWidth / 2 ) { myleft = user_camera.clientWidth / 2 ; } if (myleft + user_camera.clientWidth / 2 > document .body .clientWidth ) { myleft = document .body .clientWidth - user_camera.clientWidth / 2 ; } user_camera.style .left = myleft + 'px' ; user_camera.style .top = mytop + 'px' ; } function sliderMove (e ) { if (that.camera_big ) { return } user_camera.style .left = e.clientX + 'px' ; user_camera.style .top = e.clientY - (user_camera.clientHeight / 2 ) + 'px' ; } },
图片置灰 1 2 3 4 5 6 7 8 .userhead .gray { -webkit-filter : grayscale (100% ); -moz-filter : grayscale (100% ); -ms-filter : grayscale (100% ); -o-filter : grayscale (100% ); filter : grayscale (100% ); filter : gray; }
预处理脚本 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 const path = require ('path' );mainWindow = new BrowserWindow ({ webPreferences : { preload : path.join (__dirname, 'preload.js' ), }, }); const {ipcRenderer, remote, clipboard} = require ('electron' );window .addEventListener ('DOMContentLoaded' , () => { const element = document .getElementById ('chrome-version' ); if (element) { element.innerText = process.versions ['chrome' ]; } });
显示窗口 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 function showWin (mWin ) { if (mWin && !mWin.isDestroyed ()) { if (mWin.isMinimized ()) { mWin.restore (); } mWin.show (); mWin.focus (); app.focus (); mWin.setAlwaysOnTop (true , "screen-saver" ); setTimeout (() => { mWin.setAlwaysOnTop (false ); }, 500 ); } }
注意
win.moveTop() 在 Windows 上基本无效,在 macOS 上更是被系统直接忽略。 (Apple 的窗口管理策略不允许后台应用靠代码把自己强行提到最前,除非应用当前就是前台活跃应用 )