今天开始配置一个完整的项目,如何搭建一个登录页面。登录页面采用ui部分为自定义,没有采用element-plus。该项目背景透明、CSS圆角、标题栏和菜单全部隐藏,采用自定义“关闭”和“最小化”按钮(主进程与渲染进程之间通信)、自定义桌面图标、r任务栏图标等。
Electron分为主进程和渲染进程:
主进程:每个 Electron 应用程序都有一个主进程,作为应用程序的入口点。主进程在 Node.js 环境中运行,这意味着它能够
require
模块化和使用所有 Node.js API。主要目的是使用 BrowserWindow模块创建和管理应用程序窗口。渲染进程:由于
Electron
使用Chromium
来展示页面。每个Electron
的页面都在运行着自己的进程,这样的进程我们称之为渲染进程。也可以理解为每创建一个web
页面都会创建一个渲染进程,每个web
页面都运行在它自己的渲染进程中,每个渲染进程是独立的,它只关心它所运行的页面。
yarn create vite electron-project --template vue-ts
yarn add element-plus
yarn add --dev concurrently cross-env electron-builder wait-on
"scripts": {
"electron:serve": "concurrently -k \"yarn dev\" \"yarn electron\"",
"electron:build": "vite build && electron-builder",
"dev": "vite",
"build": "vue-tsc --noEmit && vite build",
"preview": "vite preview",
"electron": "wait-on tcp:4000 && cross-env NODE_ENV=development electron ."
},
import {createRouter, createWebHashHistory} from 'vue-router';
import login from "../view/login.vue"
const routes = [
{
path: '/',
redirect: '/login'
},
{
path: '/login',
name: 'login',
component: login
}
]
const router = createRouter({
history: createWebHashHistory(),
routes
})
const ipc = require('electron').ipcRenderer
router.beforeEach((to, from, next) => {
if (to.path === '/login') return next()
const token = localStorage.getItem('access-token')
if (!token) {
ipc.send("relaunch");
}
next()
})
export default router;
const { app, BrowserWindow, dialog, globalShortcut } = require('electron')
const electron = require('electron');
const path = require('path')
const ipc = require('electron').ipcMain;
const Menu = electron.Menu;
const Tray = electron.Tray;
var appTray = null;
process.env['ELECTRON_DISABLE_SECURITY_WARNINGS'] = 'true';
ipc.on('new-window', function () {
mainWindow.loadURL(url.format({
pathname: path.join(__dirname, '../dist/main.html'),
protocol: 'file:',
slashes: true
}))
})
const NODE_ENV = process.env.NODE_ENV;
const clearObj = {
storages: ['appcache', 'filesystem', 'localstorage', 'shadercache', 'websql', 'serviceworkers', 'cachestorage']
};
async function createWindow() {
const mainWindow = new BrowserWindow({
frame: false,
hasShadow: false,
transparent: true,
backgroundColor: '#00000000',
width: 960,
height: 640,
useContentSize: true,
resizable: false,
show: false,
icon: 'src/assets/icon/fav256.ico',
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
enableRemoteModule: true,
nodeIntegration: true,
webSecurity: false,
contextIsolation: false
}
})
mainWindow.setAppDetails({
appId: "com.successkaoyan",
appIconPath: "./src/assets/icon/fav256.ico",
appIconIndex: 0,
relaunchCommand: "Meeting Room",
relaunchDisplayName: "Meeting Room",
})
ipc.on('login', () => {
mainWindow.setSize(1260, 750);
mainWindow.center();
})
const gotTheLock = app.requestSingleInstanceLock()
if (!gotTheLock) {
app.quit()
} else {
app.on('second-instance', (event, commandLine, workingDirectory) => {
if (mainWindow) {
if (mainWindow.isMinimized()) mainWindow.restore()
mainWindow.focus()
mainWindow.show()
}
})
}
ipc.on('min', e => mainWindow.minimize());
ipc.on('max', e => {
if (mainWindow.isMaximized()) {
mainWindow.unmaximize()
} else {
mainWindow.maximize()
}
});
ipc.on('close', e => mainWindow.hide());
ipc.on('activate', e => {
mainWindow.setFullScreen(true);
mainWindow.maximize()
});
ipc.on('relaunch', e => {
app.relaunch(); app.exit();
})
var trayMenuTemplate = [
{
label: '退出',
click: function () {
mainWindow.webContents.session.clearStorageData(clearObj);
app.quit();
}
}
];
mainWindow.on("close",()=>{
mainWindow.webContents.session.clearStorageData(clearObj);
})
if (NODE_ENV === "development") {
trayIcon = path.join(app.getAppPath(), 'src/assets/icon/fav32.ico');
mainWindow.webContents.openDevTools()
} else {
trayIcon = path.join(__dirname, 'fav32.ico');
}
appTray = new Tray(trayIcon);
const contextMenu = Menu.buildFromTemplate(trayMenuTemplate);
appTray.setToolTip('Meeting Room');
appTray.setContextMenu(contextMenu);
appTray.on('click', function () {
mainWindow.show();
})
mainWindow.setMenu(null);
await mainWindow.loadURL(
NODE_ENV === "development" ?
"http://localhost:3000" :
`file://${path.join(__dirname, "../dist/index.html")}`
)
mainWindow.show()
globalShortcut.register('CommandOrControl+Shift+i', function () {
mainWindow.webContents.openDevTools()
})
globalShortcut.register('CommandOrControl+T', () => {
mainWindow.maximize()
})
globalShortcut.register('CommandOrControl+M', () => {
mainWindow.unmaximize()
})
globalShortcut.register('CommandOrControl+H', () => {
mainWindow.close()
})
}
app.whenReady().then(() => {
createWindow()
})
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
const gotTheLock = app.requestSingleInstanceLock()
if (!gotTheLock) {
app.quit()
}
app.disableHardwareAcceleration()
window.addEventListener("DOMContentLoaded",() => {
const replaceText = (selector,text) =>{
const element = document.getElementById(selector);
if (element) element.innerText = text;
};
for(const dependency of ["chrome","node","electron"]){
replaceText(`${dependency}-version`,process.versions[dependency])
}
});