Electron的学习

目录

项目初始化可以看官网非常详细

快速入门

主要需要看下窗口的配置

js 复制代码
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    center: true,
    // frame: false, //创建无边框窗口
    // titleBarStyle: "hidden", //隐藏默认的标题栏
    // 隐藏菜单
    // autoHideMenuBar: true,
    webPreferences: {
      preload: path.join(__dirname, "preload.js"),
      webviewTag: true, //允许使用<webview>标签
      // offscreen: true, //离屏渲染
    },
  });

根路径创建.vscode文件夹

创建launch.json文件,用来调试

json 复制代码
{
  "version": "0.2.0",
  "compounds": [
    {
      "name": "Main + renderer",
      "configurations": ["Main", "Renderer"],
      "stopAll": true
    }
  ],
  "configurations": [
    {
      "name": "Renderer",
      "port": 9222,
      "request": "attach",
      "type": "chrome",
      "webRoot": "${workspaceFolder}"
    },
    {
      "name": "Main",
      "type": "node",
      "request": "launch",
      "cwd": "${workspaceFolder}",
      "runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron",
      "windows": {
        "runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron.cmd"
      },
      "args": [".", "--remote-debugging-port=9222"],
      "outputCapture": "std",
      "console": "integratedTerminal"
    }
  ]
}

主进程和渲染进程之前的通信

ipcRenderer.sendipcMain.on的使用
  1. preload.js中引入contextBridge, ipcRenderer进行消息注册
js 复制代码
const { contextBridge, ipcRenderer } = require("electron");

contextBridge.exposeInMainWorld("myAPI", {
  setTitle: (title) => {
    ipcRenderer.send("set-title", title);
  },
});
  1. main.js中进行消息处理
js 复制代码
app.on("ready", () => {
  // 设置标题
  ipcMain.on("set-title", handleSetTitle);
  createWindow();
});

/**
 * @description 设置title
 */
function handleSetTitle(event, title) {
  const webContents = event.sender;
  const win = BrowserWindow.fromWebContents(webContents);
  win.setTitle(title);
}
  1. renderer.js中触发事件,修改title
html 复制代码
<h1>ipcRenderer.send-ipcMain.on的使用</h1>
	<input id="title"></input>
<button id="set-title">修改title</button>
js 复制代码
/**
 * @description 修改窗口title
 */
const titleEl = document.getElementById("title");
const handleTitleBtn = document.getElementById("set-title");
handleTitleBtn.addEventListener("click", () => {
  window.myAPI.setTitle(titleEl.value);
});
ipcRenderer.invokeipcMain.handle的使用

和send-on的区别主要在于可以双向通信

  1. preload.js
js 复制代码
const { contextBridge, ipcRenderer } = require("electron");

contextBridge.exposeInMainWorld("myAPI", {
  openFile: () => ipcRenderer.invoke("dialog:openFile"),
});
  1. main.js
js 复制代码
app.on("ready", () => {
  // 获取文件
  ipcMain.handle("dialog:openFile", handleOpenFile);
  createWindow();
});

/**
 * @description 打开文件选择弹窗
 */
async function handleOpenFile() {
  const { canceled, filePaths } = await dialog.showOpenDialog({});
  if (!canceled) {
    return filePaths[0];//返回值给invoke
  }
}
  1. renderer.js
html 复制代码
    <button type="button" id="file-btn">Open a File</button>
    File path: <strong id="file-path"></strong>
js 复制代码
/**
 * @description 打开文件
 */
const handleFileBtn = document.getElementById("file-btn");
const filePath = document.getElementById("file-path");
handleFileBtn.addEventListener("click", async () => {
  const path = await window.myAPI.openFile();
  filePath.innerHTML = path;
});

切换主题模式

js 复制代码
const {
  dialog,
  nativeTheme,
  globalShortcut,
  nativeImage,
} = require("electron");

app.on("ready", () => {
  // 设置主题
  ipcMain.handle("trigger-mode", triggerMode);
  createWindow();
});

/**
 * @description 设置主题
 */
function triggerMode() {
  if (nativeTheme.shouldUseDarkColors) {
    nativeTheme.themeSource = "light";
  } else {
    nativeTheme.themeSource = "dark";
  }
  return nativeTheme.shouldUseDarkColors;
}

文件拖放保存

  1. 注册事件
js 复制代码
contextBridge.exposeInMainWorld("myAPI", {
  startDrag: (fileName) => ipcRenderer.send("ondragstart", fileName),
});
  1. 处理事件
js 复制代码
app.on("ready", () => {
  // 文件的拖放保存
  ipcMain.on("ondragstart", fileDrag);
  createWindow();
});

/**
 * @description 原生文件拖放
 */
function fileDrag(event, filePath) {
  // 文件拖放
  const iconName = path.join(__dirname, "doc.png"); //icon
  event.sender.startDrag({
    file: path.join(__dirname, filePath),
    icon: iconName,
  });
}
  1. 给元素添加拖拽事件
js 复制代码
/**
 * @description 原生文件的拖拽
 */
document.getElementById("drag").ondragstart = (event) => {
  event.preventDefault();
  window.myAPI.startDrag("test.txt");
};
  1. 根路径准备一个test.txt文件

消息通知

js 复制代码
//main.js
app.on("ready", () => {
  createWindow();
  ipcMain.on("open-message", openMessage);
});

/**
 * @description 打开消息
 */
function openMessage(event, message) {
  const notice = new Notification({
    title: "消息",
    body: message,
  });
  notice.show();
  notice.on("click", () => {
    console.log("点击了通知");
  });
}

进度展示

js 复制代码
//main.js
app.on("ready", () => {
  // 设置进度条
  ipcMain.handle("progress", setProgress);
  createWindow();
});

/**
 * @description 设置进度条
 */
function setProgress(event, num) {
  const webContents = event.sender;
  const win = BrowserWindow.fromWebContents(webContents);
  if (num >= 1) {
    win.setProgressBar(-1); //-1完成
    return true;
  } else {
    win.setProgressBar(num);//num:0-1
    return false;
  }
}


图标闪烁

js 复制代码
//main.js
app.on("ready", () => {
  // 闪烁
  ipcMain.on("flash", setFlash);
  createWindow();
});

/**
 * @description 设置闪烁
 */
function setFlash(event) {
  const webContents = event.sender;
  const win = BrowserWindow.fromWebContents(webContents);
  win.flashFrame(true);
}

自定义菜单

js 复制代码
/**
 * @description 添加菜单
 */
function addMenu() {
  const menu = new Menu();
  const submenu = new Menu();
  menu.append(new MenuItem({ label: "测试", submenu }));
  Menu.setApplicationMenu(menu);
  submenu.append(new MenuItem({ label: "测试1" }));
}

自定义右键菜单

  1. 监听右键菜单
js 复制代码
//renderer.js
  /**
   * @description 监听右键菜单
   */
  window.addEventListener("contextmenu", async (e) => {
    e.preventDefault();
    const menu = [
      {
        label: "Run Code",
        click: true,
      },
      {
        label: "转到定义",
        click: true,
      },
      {
        type: "separator",
      },
      {
        label: "复制",
        click: true,
      },
    ];
    const clickOne = await window.myAPI.addContextMenu(menu);
    console.log(clickOne);
  });
  1. 添加菜单
js 复制代码
//main.js
/**
 * @description 添加右键菜单
 */
function addContextMenu(event, contextMenu) {
  return new Promise((resolve) => {
    const menuReal = contextMenu.map((item) => {
      if (item.click) {
        return {
          ...item,
          click: () => {
            resolve(item.label);
          },
        };
      } else {
        return item;
      }
    });
    const menu = Menu.buildFromTemplate(menuReal);
    menu.popup({
      window: BrowserWindow.fromWebContents(event.sender),
    });
  });
}
相关推荐
XiaoYu20027 分钟前
第8章 Three.js入门
前端·javascript·three.js
这个一个非常哈18 分钟前
element之,自定义form的label
前端·javascript·vue.js
李瑞丰_liruifengv34 分钟前
Claude Agent SDK 最简玩法:几行代码配合 Markdown 轻松搭建 Agent
javascript·人工智能·程序员
bobringtheboys42 分钟前
[el-tag]使用多个el-tag,自动判断内容是否超出
前端·javascript·vue.js
尽欢i44 分钟前
用 return“瘦身“if-else:让代码少嵌套、好维护
前端·javascript
程序员Agions1 小时前
小程序"邪修"秘籍:那些官方文档不会告诉你的骚操作
前端·javascript
小白探索世界欧耶!~1 小时前
用iframe实现单个系统页面在多个系统中复用
开发语言·前端·javascript·vue.js·经验分享·笔记·iframe
一只爱吃糖的小羊2 小时前
从 AnyScript 到 TypeScript:如何利用 Type Guards 与 Type Predicates 实现精准的类型锁死
前端·javascript·typescript
持续升级打怪中2 小时前
ES6 Promise 完全指南:从入门到精通
前端·javascript·es6
wulijuan8886662 小时前
Web Worker
前端·javascript