nodejs的GUI基础electron(1)


2019-4-7 nodejs electron

Electron

  1. 安装
  2. 目录结构
  3. 解析代码

初步使用

electron 的进程

在 electron 中 被 electron 直接运行的脚本 package 指定的 main 脚本为主进程,而所有的 web 界面运行在一个独立的进程中,属于渲染进程,我们可以通过主进程创建一个渲染进程,但是当一个 web 界面被销毁的时候对应的渲染进程也会被终止.

node

在 electron 中可以使用所有的 nodejs 的的接口

app 对象

这个对象提供了一系列对象事件来控制整个应用程序的生命周期,从打开到关闭.同时也有提供一些方法管理应用程序的状态和行为.

BrowserWindow 窗口

创建和控制浏览器窗口,实现显示界面,每一个 BrowserWindow 对象都是一个渲染进程,同时该对象也提供了各种操控的 api 包括事件属性和方法

bw1.webContents

类似于浏览器中的 window,这个对象下由个方法 opendevtools 开启调试,与窗口有关的内容都是通过这个来操纵的.

loadFile()

加载页面(也就是我们的要显示的内同),页面的地址使用相对路径,相对路径相对于应用程序的根目录,记载本地的协议

loadurl

使用 URL 协议加载文件可以时 HTTP 协议 也可以时 file 协议 ,加载远程协议

窗口

一般窗口 无边框窗口 透明窗口

无边框窗口 frame:false 主要用来实现所有的按钮自定义 无边框的窗口先要达到点击拖动效果 可以使用 css 中的 -webkit-app-region:drag 这个属性 透明窗口 frame:false transparent:true

父子窗口

在子窗口的 options 内部增加 parent 选项 value 指向父窗口,子窗口挂载在父窗口上 永远在父窗口前面,会同时被关闭.

模态窗口

parent:父窗口, model:true 子窗口此使会禁用父窗口 类似于 alert

菜单

有 normal submenu separator 以及 checkbox 和 redio 五种菜单类型

```javascript
let m1 = new Menu() //创建菜单
let mi1 = new MenuItem({
  type: 'normal',
  label: '文件'
}) //内部为options
let mi2 = new MenuItem({
  type: 'submenu',
  label: '查看',
  submenu: [
    {
      type: 'normal',
      label: '查看文件'
    },
    {
      type: 'separator' //菜单的分隔符
    },
    {
      type: 'normal',
      label: '查看文件夹'
    },
    {
        type:'checkbox'
        label:'选项1'
        checked:true //这个选项等到选中状态
    },
      {
        type:'radio'
        label:'aaaaa'
        checked:true //这个选项等到选中状态
    },  {
        type:'radio'
        label:'bbbbb'

    }
  ]
})
m1.append(mi1)
m1.append(mi2)
//指定该菜单显示的主题 具体哪个窗口  右键  上下文位置
/**
 * 菜单位置  1 顶层带单 2 上下文菜单
 */
//这个时menu  下的顶层方法  把菜单添加到窗口的最顶层
Menu.setApplicationMenu(m1)
```

icon 菜单前面的小图标 visiabled 是否可见 enabled 是否可用

角色

也就是系统已经预设好的菜单,然后我们使用把他们赋值到按键上

```javascript
let mi1 = new MenuItem({
  role: 'quit',
  label: '退出'
})
```

菜单事件

```javascript
let mi1 = new MenuItem({
  type: 'normal',
  label: '退出',
  click() {
    app.quit()
  }
})
```

数据共享与通信

如果有两个窗口 或者渲染进程和主进程之间的通信

- 在渲染进程中不能直接获取到主进程中的数据的 ,在渲染进程中通过 electron 的 remote 在渲染进程中拿到主进程模块,该对象下有一个方法 getGlobal()

  ```javascript
  在 外部  进程把变量挂载到global  上
  <script>
    const {remote} = require('electron') ;//引入remote 模块 console.log(remote)//
    console.log(remote.getGlobal('username'))
  </script>
  ```

- 通过进程通信 IPC ipcrenderer ipcmain

  ```javascript
  ipcRenderer.send(channel[,arg1][,arg2]....)//只能在渲染进程中使用
  ipcMain.on(channel,listener)
  listener(e,data) //监听
      e.sender.send()//回复
  //具体的实现
  // 1 在渲染进程
   const {
      remote,
      ipcRenderer
  } = require('electron')
   const aaaBtn = document.getElementById('aaa')
  aaaBtn.onclick = () => {
      ipcRenderer.send('getdata', 'username')//发送请求信息
  }
  // 2 在主进程中

    ipcMain.on('getdata', (e, data) => {//监听到 渲染进程的请求   e  事件对象   data  对面的请求数据
      console.log(e)
   console.log(data)
  e.sender.send('sendData', datas[data]) //发送 相应数据  sendData 频道名称 第二个参数 数据
   })
   //3 在渲染进程中
   ipcRenderer.on('sendData', (e, data) => { //获取到数据
      console.log(data)
  })

  ```

- 主进程主动发消息到渲染进程 通过 win.webContents.send('hello')

  ```javascript
  win.webContents.send('hello', 'hello world')
  // 在渲染京城中 通过ipcRenderer.on()
  ipcRenderer.on('hello', (e, data) => {
    console.log(data)
  })
  ```

- 多个窗口之间的数据传递,通过浏览器的 API storage 或者 indexedDB,多个窗口之间其实时同域下的.

  ```javascript
  localstorage.setItem('val', 'hahah')
  // 在其他窗口之间
  localstorage.getItem('val')
  ```

- 在渲染进程中 可以使用 remote.app.exit() 退出窗口
- 在渲染京城中最小化 remote.getcurrentWindow()//这个方法返回当前的渲染进程的窗口 渲染进程窗口.minimize() 最小化

通知 notification

在 win7 和 mac 系统上可以实现 右下角的通知信息功能

election 打包

打包的框架 election-builder

NSIS

帮助生成程序的安装打包向导

```javascript
"win": {
  "icon": "./logo.png",
  "target": [
    "nsis"
  ]
},
"nsis": {
  "oneclick": false, //一键生成安装
  "allowToChangeInstallationDirectory": true, //允许安装更改目录
  "installerIcon": "./logo.png", //安装的图标
  "installerHeader": "",//安装的头
  "license": "./source/license.text"//授权信息
}
```