前言:
因为工作需要使用Electron做桌面应用程序,了解一下学习成本最低的只有Electron。直接结合Node.js + Vue.js 可以快速实现使用,当然了解的并不深入。这里做一下记录。
顺便吐槽一下遇到一个问题,就是Electron打包后会出现部分Node.js的node_modules库找不到,当然了也找到了解决方式。
Electron文档:https://www.electronjs.org/
Electron-builder文档:https://www.electron.build/
1.开始
1.1:创建一个Vue工程 (我用的Vue-cli3)
vue create project
1.2:安装Electron
//1.3步骤安装 electron-builder会自动完成。这里是我自己写的顺便带入参数的含义
vue add electron-builder
1.3:创建完工程在project/src 目录下创建 background.js 文件,并写入(这是Electron的主文件)
'use strict'
import { app, protocol, BrowserWindow, Menu, screen } from 'electron';
const isDevelopment = process.env.NODE_ENV !== 'production';
const path = require("path");
/*******************************************************************************/
let win; //windows父窗口
/*******************************************************************************/
import {
createProtocol
} from 'vue-cli-plugin-electron-builder/lib';
import installExtension, {
VUEJS_DEVTOOLS
} from 'electron-devtools-installer';
///
//禁止开启多个应用程序
const gotTheLock = app.requestSingleInstanceLock();
if (!gotTheLock) {
app.quit();
}
//创建window主窗口
function createWindow() {
// Create the browser window.
win = new BrowserWindow({
width: process.env.WEBPACK_DEV_SERVER_URL ? 1000 : 350, //窗口宽度
height: 600, //窗口高度
x: process.env.WEBPACK_DEV_SERVER_URL ? screen.getPrimaryDisplay().workAreaSize.width - 1000 : screen
.getPrimaryDisplay().workAreaSize.width - 350, //设置窗口位置
y: screen.getPrimaryDisplay().workAreaSize.height - 600, //设置窗口位置
icon: `${__static}/logo.ico`, //设置窗口左上角图标
frame: false, //无边框
resizable: false, //禁止窗口缩放
transparent: true, //窗口透明 * 只在打包未调试状态下有效
skipTaskbar: true, //任务栏不显示窗口
acceptFirstMouse: true, //单击激活窗口
webPreferences: {
/* Use pluginOptions.nodeIntegration, leave this alone
See nklayman.github.io/vue-cli-plugin-electron-builder/guide/security.html#node-integration
for more info
nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION
*/
webSecurity: false,
nodeIntegration: true,
contextIsolation: false,
nativeWindowOpen: true,
nodeIntegrationInWorker: true,
enableRemoteModule: true
// preload: path.join(__dirname, '../src/views/renderer.js'), //在加载其他脚本前,先执行此脚本,可使用Node.js API
}
})
win.setResizable(false); //设置用户是否可以手动调整窗口大小。
win.setMaximizable(false); //设置用户是否可以手动最大化窗口
win.setSkipTaskbar(true); //窗口不显示任务栏
// win.setProgressBar(0.5); //任务栏 进度显示
// win.flashFrame(true); //任务栏窗口闪烁
// win.maximize();
if (process.env.WEBPACK_DEV_SERVER_URL) {
// Load the url of the dev server if in development mode
win.loadURL(process.env.WEBPACK_DEV_SERVER_URL); //编译环境下加载路径
if (!process.env.IS_TEST) win.webContents.openDevTools(); //编译环境下开启调试
} else {
createProtocol('app');
// win.webContents.openDevTools();
// Load the index.html when not in development
win.loadURL('app://./index.html'); //打包环境下加载路径
}
win.on('closed', () => {
win = null;
});
win.once("ready-to-show", () => {
// console.log(process.argv)
// if (process.argv.indexOf("--openAsHidden") < 0)
// win.show();
});
win.on("unresponsive", () => {
console.log("程序无响应崩溃")
})
}
// Scheme must be registered before the app is ready
protocol.registerSchemesAsPrivileged([{
scheme: 'app',
privileges: {
secure: true,
standard: true
}
}])
// Quit when all windows are closed.
app.on('window-all-closed', () => {
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit();
}
})
app.on('activate', () => {
// On macOS it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (win === null) {
//初始化WiFi模块
// Utils.init("ERR_INIT");
// //初始化消息通讯模块
// EventEmitter();
}
})
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', async () => {
//创建Windows窗口
createWindow();
})
// 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();
})
}
}
1.4:添加Vue-Router路由
cnpm install vue-router --save
1.5:修改main.js
import Vue from 'vue'
import App from './App.vue'
//添加
import router from './router'
Vue.config.productionTip = false
new Vue({
router, //添加
render: h => h(App),
}).$mount('#app')
1.6:src目录下创建router文件夹并创建index.js文件写入:
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
const originalPush = Router.prototype.push
//修改原型对象中的push方法
Router.prototype.push = function push(location) {
return originalPush.call(this, location).catch(err => err)
}
export default new Router({
// mode: 'history',
mode: process.env.IS_ELECTRON ? 'hash' : 'history',
base: process.env.BASE_URL,
routes: [
{
path: '/',
name: 'home',
component: () =>import('@/views/home')
}
]
})
1.7:修改App.vue视图主文件。
<template>
<div id="app">
<div id="app">
<router-view></router-view>
</div>
</div>
</template>
<script>
export default {
name: 'App',
components: {
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
2.完成
2.1:在管理员命令窗口执行
yarn electron:serve
下篇发布打包配置