electron基础(一)

Electron

npx

作用:

  1. 调用项目安装的模块
- npx 想要解决的主要问题,就是调用项目内部安装的模块。比如,项目内部安装了测试工具 Mocha。($ npm install -D mocha)
- 一般来说,调用 Mocha ,只能在项目脚本和 package.json 的scripts字段里面, 如果想在命令行下调用,必须像这样(// 项目的根目录下执行  $ node-modules/.bin/mocha --version)。
- npx 就是想解决这个问题,让项目内部安装的模块用起来更方便,只要像下面这样调用就行了。(npx mocha --version)
  1. 避免全局安装模块
- 除了调用项目内部模块,npx 还能避免全局安装的模块。比如,create-react-app这个模块是全局安装,npx 可以运行它,而且不进行全局安装。($ npx create-react-app my-react-app)
- 上面代码运行时,npx 将create-react-app下载到一个临时目录,使用以后再删除。所以,以后再次执行上面的命令,会重新下载create-react-app。

原理:

  • npx 的原理很简单,就是运行的时候,会到node_modules/.bin路径和环境变量$PATH里面,检查命令是否存在。
  • 由于 npx 会检查环境变量$PATH,所以系统命令也可以调用。(// 等同于 ls $ npx ls)

electron应用

hello world

  1. 主进程
// main.js
const electron = requrie('electron');
const app = electron.app; // 控制应用程序的事件生命周期
const BrowserWindow = electron.BrowserWindow; // 创建和控制浏览器窗口
let mainWindow = null; // 主窗口

app.on('ready', () => {
    
    
    mainWindow = new BrowserWindow({
    
    
        width: 900,
        height: 900,
        webPreferences: {
    
    
            nodeIntegration: true // 配置渲染进程可以使用nodejs
        }
    })
    mainWindow.loadFile('./index.html') // 加载渲染文件
    mainWindow.on('close', () => {
    
    
        mainWindow = null; // 窗口关闭时销毁主窗口
    })
})
  1. 渲染进程
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Hello world</title>
</head>

<body>
    <button id="btn">展示</button>
    <div id="show"></div>

    <script src="./render/index.js"></script>
</body>

</html>
  1. 渲染进程js交互
// 以读取文件为例
var fs = require('fs');
window.onload = function() {
    
    
    const btn = document.querySelector('#btn');
    const show = document.querySelector('#show')
    btn.addEventListener('click', function() {
    
    
        fs.readFile('readMe.text', function(err, data) {
    
    
            show.innerHTML = data.toString()
        })
    })
}
  1. 运行

electron .

remote模块

作用: 在渲染进程中使用主进程模块
使用:

// 首先需要在主进程中的webPreferences中配置 enableRemoteModule: true,
mainWindow = new BrowserWindow({
    
    
    width: '100%',
    height: '100%',
    webPreferences: {
    
    
        nodeIntegration: true,
        enableRemoteModule: true,
    },
});
// 渲染进程 index.js
const BrowserWindow = require('electron').remote.BrowserWindow // 在渲染进程中使用主进程中的BrowserWindow
window.onload = function() {
    
    
    const open = document.querySelector('#open') // 在页面中打开新的窗口
    open.onclick = function() {
    
    
        let newWin = new BrowserWindow({
    
    
            width: 900,
            height: 900,
        });
        newWin.loadFile('../index.html');
        newWin.on('close', () => {
    
    
            newWin = null;
        });
    };
}

ELectron中菜单的创建和绑定事件

// 构建menu菜单文件
const {
    
    
    Menu,
    BrowserWindow
} = require('electron')

const template = [{
    
    
        label: '菜单一',
        submenu: [{
    
    
                label: '子菜单一',
                accelerator: 'ctrl + n', // 设置快捷键
                click: () => {
    
    
                    let newWin = new BrowserWindow({
    
    
                        width: 800,
                        height: 800,
                        webPreference: {
    
    
                            nodeIntegration: true
                        }
                    })
                }
            },
            {
    
    
                label: '子菜单二'
            }
        ]
    },
    {
    
    
        label: '菜单二',
        submenu: [{
    
    
                label: '子菜单一'
            },
            {
    
    
                label: '子菜单二'
            }
        ]
    }
]

const m = Menu.buildFromTemplate(template)
Menu.setApplicationMenu(m)

// 最后再把这个文件引入主线程main.js中就可以啦

打开调试窗口

// 在主进程中使用主窗口的对象
mainWindow.webContents.openDevTools({
    
    
    mode: 'detach'
}) //不写mode:detach默认是合并的

右键菜单

// 制作模板
const rightTemplate = [{
    
    
        label: '复制',
        accelerator: 'ctrl+c'
    },
    {
    
    
        label: '粘贴',
        accelerator: 'ctrl+v'
    }
]

const m = remote.Menu.buildFromTemplate(rightTemplate)

// 在渲染进程中绑定右键事件
window.addEventListener('click', function(e) {
    
    
    e.preventDefault()
    m.popup({
    
     // 弹出窗口
        window: remote.getCurrentWindow()
    })
})

Electron中通过链接打开浏览器(shell模块)

const remote = require('electron').remote
const {
    
    
    BrowserWindow,
    shell
} = remote

const aHref = document.querySelector('#baidu')
aHref.onclick = function(e) {
    
    
    e.preventDefault()
    const href = aHref.href
    shell.openExternal(href)
}

Electron中嵌入网页和打开子窗口

  1. electron中嵌入网页(BrowserView)
// 主进程中 main.js
const BrowserView = electron.BrowserView
const view = new BrowserView()
mainWindow.setBrowserView(view) //主进程添加BrowserView
view.setBounds({
    
     //设置大小位置
    x: 0,
    y: 100,
    width: 800,
    height: 800
})
view.webContents.loadURL('https://www.baidu.com') // BrowserView内容
  1. 打开子窗口(window.open(url))

子窗口向父窗口通信

方法:window.opener.postMessage (注意:window.opene()打开的是子窗口,new BrowserWindow()打开的是新的窗口,与原先窗口没有直接关系)

// 父窗口
window.open('other.html') // 绑定事件跳转子窗口
window.addEventListener('message', function(data) {
    
     // 监听子窗口传来的消息
    alert(data.data)
})

// 子窗口中使用window.opener.postMessage()
// 绑定事件发送消息
btn.onclick = function() {
    
    
    window.opener.postMessage('发送消息给父窗口')
}

选择文件对话框(dialog)

const {
    
    
    dialog
} = require('electron').remote
// 事件绑定
btn.onclick = () => {
    
    
    dialog.showOpenDialog({
    
    
        defaultPath: '/', // 默认为项目根路径
        title: '设置标题',
        filters: [{
    
    
            name: 'image',
            extensions: ['jpg', 'png'], // 过滤文件
        }],
        buttonLabel: '打开这个文件' // 自定义打开按钮文案
    }).then(data => {
    
    
        console.log(data.filePaths[0])  // 图片路径
    }).catch(err => {
    
    
        console.log(err)
    })
}

保存文件对话框(dialog)

const fs = require('fs')
// 不会保存空文件
dialog.showSaveDialog({
    
    
  title:'保存文件'
}).then( data => {
    
    
  console.log(data.filePath) // 保存文件的路径
  fs.writeFileSync(data.filePath,'哈哈哈哈')
}).catch( err => {
    
    
  console.log(err)
})

消息对话框(dialog)

btn.onclick = () => {
    
    
  dialog.showMessageBox({
    
    
    type:'warning'  // none、info、error、question,
    title:'设置标题',
    message:'设置消息内容',
    buttons:['是','否'] // 设置按钮交互
  }).then( result => {
    
    
    console.log(result)  // 交互的结果以数组的索引显示,result.response   0,1,2....
  }).catch( err => {
    
    
    console.log(err)
  })
}

断网提醒功能

  • 利用h5的事件监听
window.addEventListener('online',function(){
    
    
  alert('网络连接成功')
})

window.addEventListener('offline',function(){
    
    
  alert('断网了')
})

底部消息通知

btn.onclick = () => {
    
    
  const option = {
    
    
    title:'消息标题',
    body:'消息内容~~~~'
  }
  new window.Notification(option.title,option)
}

注册全局快捷键

// 主线程中(main.js)
const electron = require('electron')
const globalShortcut = electron.globalShortcut

app.on('ready',function(){
    
     // 一定要在 ready之后才能注册快捷键
  const isRegistered = globalShortcut.isRegistered('ctrl+q')   // 判断是否被注册
  if(!isRegistered){
    
    
    globalShortcut.register('ctrl+q',function(){
    
    
      // what to do
      mainWindow.loadURL('https://www.jd.com')
    })
  }
})

app.on('will-quit',function(){
    
    
  globalShortcut.unregister('ctrl+e')  // 单一注销
  globalShortcut.unregisterAll()  // 全部注销
})

剪切板功能

const {
    
     clipboard, dialog } = require('electron').remote
clipboard.writeText(code.innerHTML)
dialog.showMessageBox({
    
    
  message: '复制成功'
})

猜你喜欢

转载自blog.csdn.net/qq_36303110/article/details/112313620
今日推荐