electron 结合前端和nodejs后端的功能和优点

1,445 阅读2分钟

electron笔记

初始化项目

  1. 从github复制源码然后npm install

  2. 用命令行工具

    yarn create electron-app appname // appname是应用名字
    

    命令行工具创建出来的项目没有preload和render.js main.js替换成为了index.js

    electron 的优势是结合了nodejs和浏览器环境,render.js默认是在浏览器环境,但可以通过主进程(main.js/index.js)的的new BrowserWindow({webPreferences:{nodeIntegration:默认是false})配置让它具有nodejs的环境,改成true就可以了

    const mainWindow = new BrowserWindow({
        width: 800,
        height: 600,
        webPreferences:{
          nodeIntegration:true
        }
      });
    

使用html和nodejs的api

用命令行初始化项目。先在index.js中开启nodeIntegration,然后可以用drop事件获得文件然后在fs读取之后放到界面上。

const fs = require('fs')
let holder = document.querySelector('#holder')
console.log(holder);
holder.addEventListener('drop',(e)=>{
  console.log(e)
  e.preventDefault() //取消默认
  e.stopPropagation() //阻止冒泡
  for(const file of e.dataTransfer.files){
    console.log(file)
    console.log('路径',file.path)
    fs.readFile(file.path,(err,data)=>{
      let list = document.querySelector('#readList')
      if(err){
        console.log(err)
        return
      }else{
        list.innerHTML += `
        <h3>${file.name}</h3>
        <pre>${data.toString('utf-8')}</pre>
        `
      }

    })
  }
})
holder.addEventListener('dragover',(e)=>{
  e.preventDefault() //取消默认
  e.stopPropagation() //阻止冒泡
})

webview

webview可以在桌面的应用界面上打开其他网页.但是要在webPreference中设置 webviewTag:true

webview有监听事件did-start-loadingdid-stop-loading

const webview = document.querySelector('webview')
webview.addEventListener('did-start-loading',()=>{
  console.log('正在加载')
})
webview.addEventListener('did-stop-loading',()=>{
  console.log('加载完毕')
})

可以在webview中插入css

const webview = document.querySelector('webview')
webview.addEventListener('did-stop-loading',()=>{
  console.log('加载完毕')
  webview.insertCSS(`#su{background:red!important;}`)
})

可以在webview中插入js

const webview = document.querySelector('webview')
webview.addEventListener('did-stop-loading',()=>{
  console.log('加载完毕')
  webview.insertCSS(`#su{background:red!important;}`)
})

webview可以集成node模块

<webview id="wv" src="https://www.baidu.com" style="width: 640px;height: 480px;" nodeintegraion ></webview>

主进程和渲染进程通信

通信方式

//监听渲染进程发送到渲染事件
ipcMain.on('lc-message',(event,arg)=>{
  event.reply('lc - reply','这是主进程的答复')
  console.log(arg)
})
const createWindow = () => {
	//主动发送消息到渲染进程
  	mainWindow.webContents.send('lc-active','创建窗口之后主进程主动发送消息到渲染进程')
}

渲染进程是index.html里面的script标签或者script标签的src的js文件

 <script>
      let {ipcRenderer} = require('electron');
      //监听消息
      ipcRenderer.on('lc-active',(event,arg)=>{
        console.log("arg", arg);
        console.log("event", event);
      })
      //发送消息
      ipcRenderer.send('lc-message',"hello 主进程,我是子进程的消息")
      // 监听发送给主进程后主进程返回的消息
      ipcRenderer.on('lc-reply',(event,arg)=>{
        console.log("arg", arg);
        console.log("event", event);

      })

    </script>

渲染进程发送消息可以让主进程开新窗口

主进程代码

ipcMain.on('openNewWindows',(event,arg)=>{
  //准备打开新窗口
  createMyWindow()
})
const createMyWindow = (url) => {
  // Create the browser window.
  const mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences:{
      nodeIntegration:true
    }
  });
  // and load the index.html of the app.
  mainWindow.loadFile(url);

  // Open the DevTools.
  mainWindow.webContents.openDevTools();
};

渲染进程代码

let btn = document.querySelector('#btn')
btn.addEventListener('click',function(){
    ipcRenderer.send('openNewWindows',"hello 主进程,开新窗口") //第二个参数可以传可以不传
})

dialog弹框

dialog常用语打开文件或者弹出警告,它在主进程中使用.

const { app, BrowserWindow,dialog } = require('electron');
const createWindow = () => {
  // Create the browser window.
  const mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
  });

  // and load the index.html of the app.
  mainWindow.loadFile(path.join(__dirname, 'index.html'));

  // Open the DevTools.
  mainWindow.webContents.openDevTools();
    mainWindow.on('close',(e)=>{
    e.preventDefault()
    dialog.showMessageBox(mainWindow,{
      type:'warning',
      title:'关闭',
      message:'是否关闭窗口',
      buttons:['取消','残酷关闭'] 
    }).then(index=>{
      console.log(index)
      if(index.response==1){
        app.exit()
      }
    })
    
  })
  setTimeout(()=>{
     dialog.showOpenDialog({
      /**
       * openFile 允许选择文件
       * openDirectory 允许选择文件夹
       * multiSelection 允许多选
       * showHiddenFiles 显示隐藏文件
       * createDirectory 允许创建文件夹
       */
      properties:['openFile','multiSelections']
    }).then(res=>{
      console.log("result filePath", res.filePaths);
      console.log('result cancel',res.canceled)
    })
  },2000)
};

app.quit()会触发mainWindow 'close'事件 通过on监听,app.exit()是直接退出

自带网络请求库net

性能好一点,但是封装的不好所以不好用

let req = net.request('https://www.taobao.com')
  req.on('response', (res => {
    console.log(res)
    res.on('data', data => {
      console.log(data)
    })
  }))
  req.end()

electron结合vue开发

安装vue-cli后安装vue init simulatedgreg/electron-vue your-project-name