美文网首页
vue-cli 里面引入electron 以及基本的配置

vue-cli 里面引入electron 以及基本的配置

作者: 冰落寞成 | 来源:发表于2021-05-12 19:21 被阅读0次

引入electron,electron-builder,vue-cli-plugin-electron-builder,electron-devtools

npm i --save-dev electron

1,引入之后在package.json 文件下会自动生成

image.png

2,在vue-cli 项目src下 创建background.js

代码如下:

import { app, protocol, BrowserWindow, ipcMain, Menu, dialog, globalShortcut } from 'electron'
import {
  createProtocol
} from "vue-cli-plugin-electron-builder/lib";
const fs = require("fs")  //引入node原生fs模块
const os = require("os")
const isDevelopment = process.env.NODE_ENV !== "production";
let mainWindow
// Scheme must be registered before the app is ready
protocol.registerSchemesAsPrivileged([
  { scheme: "app", privileges: { secure: true, standard: true } }
]);
const path = require('path')
const menus = [{
  label: '视图',
  submenu: [{
    label: '刷新',
    role: 'reload'
  },
  {
    label: '退出',
    role: 'quit'
  }]
}]
const menu = Menu.buildFromTemplate(menus)

function createWindow () {
  mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    show: false,
    webPreferences: {
      enableRemoteModule: true, // 允许弹框
      webSecurity: false,
      nodeIntegration: true,
      nodeIntegrationInWorker: true, // 在Web工作器中启用了Node集成

      preload: path.join(__dirname, 'preload.js'),
      defaultEncoding: 'utf-8'
    }
  })
  mainWindow.once('ready-to-show', () => {
    mainWindow.show()
  })


  if (process.env.WEBPACK_DEV_SERVER_URL) { // 开发环境
    // Load the url of the dev server if in development mode
    mainWindow.loadURL(process.env.WEBPACK_DEV_SERVER_URL)
    if (!process.env.IS_TEST) mainWindow.webContents.openDevTools();
    globalShortcut.register('CommandOrControl+Shift+i', function () { //  使用快捷键shift+ctrl+i  调起开发工具
      mainWindow.webContents.openDevTools()
    })

  } else { //  生产环境
    // mainWindow.webContents.openDevTools() //  生产环境关闭调试工具
    // Load the index.html when not in development
    createProtocol('app')
    // Load the index.html when not in development
    mainWindow.loadURL('app://./index.html')
  }
  Menu.setApplicationMenu(menu)
}


/**
 * 初始化
 */
app.whenReady().then(() => {


  createWindow()
  app.setAppUserModelId('管理平台')
  // 点击MacOS底部菜单时重新启动窗口
  app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) {
      createWindow()
    }
  })
})

// 兼容MacOS系统的窗口关闭功能
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit()
  }
  mainWindow = null
})
// 最小化窗口(自定义导航条时)
ipcMain.on('window-min', () => {
  mainWindow.minimize()
})
// 最大化窗口(自定义导航条时)
ipcMain.on('window-max', () => {
  // 如果已经是最大化窗口就还原
  if (mainWindow.isMaximized()) {
    mainWindow.restore();
  } else {
    mainWindow.maximize()
  }
})
// 关闭窗口
ipcMain.on('window-close', () => {
  mainWindow.close()
  mainWindow = null;
  app.exit();
})

// 主进程给进程通信

ipcMain.on('toMain', function (event, arg) {

  event.sender.send('fromMain', arg); // 返回给渲染进程

});
// 下载进程
ipcMain.on('downLoad', function (event, arg) {
  mainWindow.webContents.downloadURL(arg.url);
});
// 调用文件读入方法
ipcMain.on('judgeUse', function (event, arg) {
  // 读入文件
// 异步返回
  fs.readFile("./authorize.bin", { encoding: "utf-8" }, (err, data) => {
    // if (err) {
    //   // dialog.showMessageBox({
    //   //   type: 'error',
    //   //   title: '找不到authorize.bin文件',
    //   //   message: err.path,
    //   //   buttons: ['ok']
    //   // }).then((index) => {
    //   //   if (index.response === 0) {
    //   //     mainWindow.close()
    //   //     mainWindow = null;
    //   //     app.exit();
    //   //   }
    //   // })
    //   event.sender.send('fromMain', null); // 返回给渲染进程
    // } else {
    //   event.sender.send('fromMain', data); // 返回给渲染进程
    // }
    event.reply('authorizeBack', data); // 返回给渲染进程
  })

});
// 读取本地服务的IP 地址 同步
ipcMain.on('syncGetLocalServer', function (event, arg) {
  // 读入文件,同步返回数据
  fs.readFile("./localServer.xml", { encoding: "utf-8" }, (err, data) => {
    event.returnValue=data; // 返回给渲染进程
  })
});
// 读取本地服务的IP 地址 异步
ipcMain.on('asyncGetLocalServer', function (event, arg) {
  // 读入文件
// 异步返回
  fs.readFile("./localServer.xml", { encoding: "utf-8" }, (err, data) => {
    event.reply('asyncBackLocalServer', data); // 返回给渲染进程
  })

});
//隐藏按钮
ipcMain.on('hideMenu', function (event, arg) {
  mainWindow.setMenu(null);
});
//显示按钮
ipcMain.on('showMenu', function (event, arg) {
  mainWindow.setMenu(menu);
});

// Exit cleanly on request from parent process in development mode.
if (isDevelopment) {
  if (process.platform === "win32") {
    process.on("message", data => {
      if (data === "graceful-exit") {
        app.quit();
      }
    });
  } else {
    process.on("SIGTERM", () => {
      app.quit();
    });
  }
}

3,在vue-cli 项目src下 创建 preload.js(预加载文件)

import { contextBridge, ipcRenderer } from 'electron'
window.ipcRenderer = ipcRenderer

contextBridge.exposeInMainWorld('ipcRenderer', {
  // 异步向主进程 发送消息
  send: (channel, data) => {
    let validChannels = ['toMain', 'downLoad', 'judgeUse', 'hideMenu', 'showMenu', 'window-close', 'asyncGetLocalServer']
    if (validChannels.includes(channel)) {
      ipcRenderer.send(channel, data)
    }
  },
  // 同步向主进程 发送消息,
  sendSync: (channel, data) => {
    let validChannels = ['syncGetLocalServer']
    if (validChannels.includes(channel)) {
      return ipcRenderer.sendSync(channel, data)
    }
  },
  // 异步接收主进程返回的数据
  receive: async (channel) => {
    let validChannels = ['authorizeBack', 'asyncBackLocalServer']
    if (validChannels.includes(channel)) {
      return new Promise((resolve) => {
        ipcRenderer.on(channel, (event, ...args) => {
          resolve(...args)
        })
      });

    }
  }
})

4,在package.json 里面添加 background.js 的引入

 "main": "background.js",
image.png

5, 在package.json =>scripts添加electron的启动、打包命令

"electron:build": "vue-cli-service electron:build",
    "electron:serve": "vue-cli-service electron:serve",
    "postinstall": "electron-builder install-app-deps",
    "postuninstall": "electron-builder install-app-deps"
image.png

package.json 最终配置如下:

{
  "name": "mine-exe",
  "author": {
    "name": "xd"
  },
  "description": "test",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "start": "vue-cli-service serve -open",
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint",
    "electron:build": "vue-cli-service electron:build",
    "electron:serve": "vue-cli-service electron:serve",
    "postinstall": "electron-builder install-app-deps",
    "postuninstall": "electron-builder install-app-deps"
  },
  "dependencies": {
    "@babel/polyfill": "^7.12.1",
    "axios": "^0.21.1",
    "core-js": "^3.6.5",
    "dayjs": "^1.10.4",
    "echarts": "^5.1.0",
    "electron-builder": "^22.11.1",
    "element-ui": "^2.15.1",
    "js-md5": "^0.7.3",
    "vue": "^2.6.11",
    "vue-cli-plugin-electron-builder": "^2.0.0",
    "vue-router": "^3.2.0",
    "vuex": "^3.4.0"
  },
  "main": "background.js",
  "devDependencies": {
    "@vue/cli-plugin-babel": "~4.5.0",
    "@vue/cli-plugin-eslint": "~4.5.0",
    "@vue/cli-plugin-router": "~4.5.0",
    "@vue/cli-plugin-vuex": "~4.5.0",
    "@vue/cli-service": "~4.5.0",
    "@vue/eslint-config-standard": "^5.1.2",
    "babel-eslint": "^10.1.0",
    "electron": "^12.0.7",
    "electron-devtools-installer": "^3.2.0",
    "eslint": "^6.7.2",
    "eslint-plugin-import": "^2.20.2",
    "eslint-plugin-node": "^11.1.0",
    "eslint-plugin-promise": "^4.2.1",
    "eslint-plugin-standard": "^4.0.0",
    "eslint-plugin-vue": "^6.2.2",
    "sass": "^1.26.5",
    "sass-loader": "^8.0.2",
    "vue-template-compiler": "^2.6.11"
  }
}

6,在vue.config.js 里的配置如下

const path = require('path')
const resolve = dir => path.join(__dirname, dir)
const CopyWebpackPlugin = require('copy-webpack-plugin')
const webpack = require('webpack')
const BASE_URL = process.env.NODE_EVN === 'production'
  ? './'
  : './'
const port = process.env.PORT || 8080
module.exports = {
  publicPath: BASE_URL,
  outputDir: 'mine-exe',
  assetsDir: 'static',
  lintOnSave: process.env.NODE_ENV === 'development',
  // 这里写你调用接口的基础路径,来解决跨域,如果设置了代理,那你本地开发环境的axios的baseUrl要写为 '' ,即空字符串
  devServer: {
    // proxy: 'localhost:3000'
    port,
    open: false
  },
  pluginOptions: {
    electronBuilder: {
      removeElectronJunk: false,
      preload: './src/preload.js',
      builderOptions: {
        "appId": "com.example.app",
        "productName": "智慧矿山管理平台",//项目名,也是生成的安装文件名,即aDemo.exe
        "copyright": "Copyright © 2021",//版权信息
        "directories": {
          "output": "build"//输出文件路径
        },
        "win": {//win相关配置
          "icon": "./src/assets/icon.ico",//图标,当前图标在根目录下,注意这里有两个坑
          "target": [
            {
              "target": "nsis",//利用nsis制作安装程序
              "arch": [
                "x64",//64位
              ]
            }
          ]
        },
        "nsis": {
          "oneClick": false, // 是否一键安装
          "allowElevation": true, // 允许请求提升。 如果为false,则用户必须使用提升的权限重新启动安装程序。
          "allowToChangeInstallationDirectory": true, // 允许修改安装目录
          "installerIcon": "./src/assets/icon.ico",// 安装图标
          "uninstallerIcon": "./src/assets/icon.ico",//卸载图标
          "installerHeaderIcon": "./src/assets/icon.ico", // 安装时头部图标
          "createDesktopShortcut": true, // 创建桌面图标
          "createStartMenuShortcut": true,// 创建开始菜单图标
          "shortcutName": "mine", // 图标名称
        },
      }
    },
  },
  chainWebpack: config => {
    config.resolve.alias
      .set('@', resolve('src'))
    config.entry('polyfill').add('@babel/polyfill')
  },

  css: {
    loaderOptions: {
      sass: {
        prependData: `
          @import "@/styles/variables.scss";
          @import "@/styles/mixins.scss";
        `
      }
    }
  },
  // 设为false打包时不生成.map文件
  productionSourceMap: true
}

7,在终端里使用“npm run electron:serve ” 即可打开本地EXE程序

8 在终端里使用“npm run electron:build ” 即可打包本地EXE程序:(注意有坑)

打包本地程序解决下载依赖过慢的方法如下:
https://www.jianshu.com/p/5d8ea14ce374

9 最终vue-cli 项目目录如下

红色箭头指的文件是新增的,绿色箭头指向的文件为要修改的


image.png

相关文章

网友评论

      本文标题:vue-cli 里面引入electron 以及基本的配置

      本文链接:https://www.haomeiwen.com/subject/fsdadltx.html