electron

## 什么是electron
```
Electron是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架,
是一个非常牛的跨平台的开发工具,
像我们用的vscode就是用electron开发的,electron 本质是一个浏览器,
但是里面内置了node的环境,所以可以操作本地文件。
```

- 生命周期:https://zhuanlan.zhihu.com/p/352668011
- 主进程和渲染进程:main主进程,rander渲染进程
```
主进程:适用前端技术作为app的gui,我们可以把它当做一个小型的chrom内核浏览器,负责创建和管理BrowserWindow实例以及各种应用程序事件。
它还可以执行诸如注册全局快捷方式,创建系统菜单和对话框,响应自动更新事件等操作。
应用程序的入口点将指向将在主进程中执行的JavaScript文件。
主进程以及所有node.js模块中都提供了一部分ElectronAPI(请参见下图)。
渲染过程负责运行应用程序的用户界面,换句话说,就是作为webContents实例的网页,每个页面使用自己的线程,这些线程就被称为渲染线程。
渲染进程中提供了所有DOM API,node.js API和ElectronAPI的子集(请参见下图),在一定程度上可以与操作系统进行交互。
 
```
 

## electron 安装和运行
```
默认我们都是有node环境,自行搜索,node安装。
git clone https://github.com/electron/electron-quick-start
cd electron-quick-start
npm install
npm start
```
**打包**
```
npm install --save-dev electron-packager
npm run-script package
```
```
 "package": "electron-packager . 'app' --platform=darwin --arch=x64 --icon=app.icns --out=./dist --asar --app-version=1.0.0 --ignore=\"(dist|src|docs|.gitignore|LICENSE|README.md|webpack.config*|node_modules)\"",
    "packageDarwin": "electron-packager . '应用名称' --platform=darwin --arch=x64 --icon=app.icns --out=./dist --asar --app-version=1.0.0 --ignore=\"(dist|src|docs|.gitignore|LICENSE|README.md|webpack.config*|node_modules)\"",
    "packageDarwin2": "electron-packager . '应用名称' --platform=darwin --arch=x64 --icon=app.icns --out=./dist --asar --app-version=1.0.0",
    "packageWin": "electron-packager . '应用名称' --platform=win32 --arch=x64 --icon=app.ico --out=./dist --asar --app-version=1.0.0 --ignore=\"(dist|src|docs|.gitignore|LICENSE|README.md|webpack.config.js|node_modules)\"",
    "packageWin2": "electron-packager . '应用名称' --platform=win32 --arch=x64 --icon=app.ico --out=./dist --asar --app-version=1.0.0",
    "start": "electron ."
    
    -----配置里面不能有汉字,要使用英语替代

```

## 部分electron案例
**如果需要使用node环境和electron部分api等需要在主进程mainjs里面配置**

```
 webPreferences: {
    nodeIntegration: true,
    contextIsolation:false,
  }

```
**1,文件拖拽**

```
  为了让用户能够通过HTML5的file API直接操作本地文件,DOM的File接口提供了对本地文件的抽象。Electron在File接口中增加了一个path属性,它是文件在系统中的真实路径。
  const fs  = require("fs");
    document.addEventListener('drop', (e) => {
      e.preventDefault();//取消默认行为
      e.stopPropagation();//阻止冒泡
      console.log(1)
      for (const f of e.dataTransfer.files) {
        console.log('File(s) you dragged here: ', f,e)
        fs.readFile(f.path,'utf-8',(err,data)=>{
          if (!e) {
            document.getElementById('text').innerHTML = data
          }
        })
      }
    });
    document.addEventListener('dragover', (e) => {
      e.preventDefault();
      e.stopPropagation();
      console.log(2)
    });

```
**2,自定义快捷键**

```
 在主进程中配置
  const {app, dialog, globalShortcut} = require('electron')
  app.on('ready', () => {
     globalShortcut.register('CommandOrControl+Alt+K', () => {
  dialog.showMessageBox({
  type: 'info',
  message: '成功!',
  detail: '你按下了一个全局注册的快捷键绑定.',
  buttons: ['好的']
})
  })
  })

  app.on('will-quit', () => {
      globalShortcut.unregisterAll()
  })

```
**3复制黏贴**

```
渲染进程
<body>
  <a href="../index.html">返回</a>
  <div id="copy-to">复制</div>
  <input type="text" id="copy-to-input">
  <div id="showCopy"></div>
  <script>
    const {clipboard} = require('electron')
      const copyBtn = document.getElementById('copy-to')
      const copyInput = document.getElementById('copy-to-input')
      const showCopy = document.getElementById('showCopy')
      copyBtn.addEventListener('click', () => {  
      clipboard.writeText(copyInput.value)
      showCopy.innerHTML=copyInput.value
    })
  </script>
</body>

```
**4webview**

```
主进程里面配置
  webPreferences: {
      webviewTag:true,
    }
    
渲染进程
<webview id="foo" src="https://www.baidu.com/"></webview>

如何操作webview
const wb = document.querySelector('#foo');
//开始加载事件监听
wb.addEventListener("did-start-loading", ()=> {
     console.log("did-start-loading...");
  })
  //停止加载事件监听
  wb.addEventListener("did-stop-loading", ()=> {
     console.log("did-stop-loading...");
  
    //注入css,视频生效,自己没生效
     wb.insertCSS(`
        body {
          display: none!important;
        }
      `)
      //注入js脚本
      wb.executeJavaScript(`
          setTimeout(()=>{
            alert("粉丝数:",111);
         }, 2000);
      `)
    //打开调试工具
      wb.openDevTools();
  })

```

**5shell对象**

```
主进程里面配置
  webPreferences: {
      enableRemoteModule:true
    }
渲染进程
<body>
  <a href="../index.html">返回</a>
  <div id='href' hrefs="https://www.baidu.com/">shell打开外部链接</div>
  <div id="openwidnows">openwidnows打开内部</div>
  <script>
    const { shell  } = require('electron')
    let dom = document.getElementById('href')
    let srt = dom.getAttribute('hrefs')
    console.log(11, srt)
    dom.onclick = function (e) {
      shell.openExternal(srt)
    }

  //在Electron10.x中,enableRemoteModule的默认值为false,也就是默认情况下是不支持使用remote模块的,因此使用remote模块的应用程序需要enableRemoteModule显式设置为true。
    var BrowserWindow=require('electron').remote.BrowserWindow;
    const path = require('path')
    const item = document.getElementById('openwidnows')
    item.onclick = function () {  
      let file = path.join(__dirname, './04.webview.html')
      let win = new BrowserWindow({ width: 800, height: 600 })
      // Load a remote URL
      win.loadURL(file)
      win.on('closed', () => {
        win = null
      })
    }
  </script>
</body>

```

**6window对象的操作**

```
父窗口打开子窗口,子窗口向父窗口发送信息
```
- 父窗口
```
<body>
  <a href="../index.html">返回</a>
  <h2>弹出子窗口</h2>
  <button οnclick="startpop()">开启</button>
  <button οnclick="closedpop()">关闭</button>
  <script>
    let win=""
    function startpop() { 
      //  win= window.open('https://www.baidu.com/', '_blank', 'top=500,left=200,frame=false,nodeIntegration=no')
       win= window.open('./06.wchild.html','popup','top=300,left=200,')
     }
    function closedpop() { 
        win.close()
     }

     window.addEventListener('message',function (e) {
       console.log(111,e)
       })
  </script>
</body>

```
- 子窗口
```
 
<body>
  <a href="../index.html">返回</a>
  <div>我是window打开的本地页面</div>
  <button οnclick="sendmsg()">向父窗口发送信息</button>
  <script>
    function sendmsg() {  
      window.opener.postMessage('这是来自子窗口问候')
      window.opener.postMessage({
        type:1,
        messageChannel:'这是来自子窗口问候'
      })
    }
  </script>
</body>

```

**7主进程menu菜单menu-js渲染进程菜单**
```
1在页面右击出现菜单
2在任务栏出现菜单
```

**8渲染进程和主进程的通讯(同步和异步)**
- 使用ipc一异步方式在进程之间发送消息是首选方法,因为他会在完成时返回,而不会阻止同一进程中的其他操作,此实例将在渲染进程发送’ping‘到主进程,然后主进程返回’pong‘,渲染进程接受
```
渲染进程
const {ipcRenderer} = require('electron')
const asyncMsgBtn = document.getElementById('async-msg')
asyncMsgBtn.addEventListener('click', () => {
  ipcRenderer.send('asynchronous-message', 'ping')
})

ipcRenderer.on('asynchronous-reply', (event, arg) => {
  const message = `异步消息回复: ${arg}`
  document.getElementById('async-reply').innerHTML = message
})

主进程
const {ipcMain} = require('electron')
ipcMain.on('asynchronous-message', (event, arg) => {
  event.sender.send('asynchronous-reply', 'pong')
})

```
 
## 结合vue开发
- ①electron-vue文档----- https://simulatedgreg.gitbooks.io/electron-vue/content/cn/
- ②脚手架安装electron-vue
```
# 如果没有 vue-cli 的话需要全局安装
npm install -g vue-cli
# 然后使用 vue-cli 来安装 electron-vue 的模板
vue init simulatedgreg/electron-vue grpc-client-electron-vue
# 安装依赖
cd grpc-client-electron-vue
yarn # or npm install
# 进入开发模式
yarn run dev # or npm run dev
开发ok,打包有问题grpc-client-electron-vue项目,
```
- ③使用ui框架antd,vue开发一样,安装依赖,引入项目,vue文件使用
```
a.  npm i --save ant-design-vue
b.   在项目src-renderer-main.js引入,
import Antd from 'ant-design-vue';
import 'ant-design-vue/dist/antd.css';
Vue.use(Antd);
```
- ④关闭eslint
```
注释掉如下的代码:
  //{
        // test: /\.(js)$/,
        // enforce: 'pre',
        // exclude: /node_modules/,
        // use: {
        //   loader: 'eslint-loader',
        //   options: {
        //     formatter: require('eslint-friendly-formatter')
        //   }
        // }
```
- ⑤跨域 
```
文件src-main-index.js 
mainWindow = new BrowserWindow({
    height: 563,
    useContentSize: true,
    width: 1000,
//允许跨域
    webPreferences:{
      webSecurity:false
    }
  })
```
- 当 node 版本高于 12 的时候,会报错:
```
解决方法:打开.electron-vue 文件夹中的 webpack.web.config.js 和 .electron-vue/webpack.renderer.config.js,
在 HtmlWebpackPlugin,添加 templateParameters,如下所示:
templateParameters(compilation, assets, options) {
        return {
          compilation: compilation,
          webpack: compilation.getStats().toJson(),
          webpackConfig: compilation.options,
          htmlWebpackPlugin: {
            files: assets,
            options: options
          },
          process,
        };
      },
```
## 最终版本
-[git地址](https://umbrella22.github.io/electron-vue-template-doc)
```
四,结合vue开发源码,可打包

开发使用vue devtools ,代码里面已经配置,首次运行时候需要下载vue-devtools ,但是安装有问题,造成原因是国内网问题,需要翻墙,打包成功以后就无须翻墙了。
import electronDevtoolsInstaller, { VUEJS_DEVTOOLS } from 'electron-devtools-installer'

function onAppReady () {
  initWindow()
  DisableButton.Disablef12()
  if (process.env.NODE_ENV === 'development') {
    electronDevtoolsInstaller(VUEJS_DEVTOOLS)
      .then((name) => console.log(`installed: ${name}`))
      .catch(err => console.log('Unable to install `vue-devtools`: \n', err))
  }
}
```


## 学习资料中文文档
- [Electron 中文文档](http://www.niuguwen.cn/kaifashouce-cat-138.html)
- [Electron 官网](http://www.electronjs.org/)
- [electron入门到精通-项目实战](https://www.bilibili.com/video/BV16f4y1q7xz?t=796&p=19)

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值