vue项目搭建electron
一、全局安装vue脚手架
npm install -g @vue/cli //若已安装不需要进行这一步
vue --version //查看脚手架版本
二、1、可使用 Vue CLI 来添加 Vue.js 到你的 Electron 项目中
vue add electron-builder //在vue项目执行
2、全局安装electron
npm install electron -g //全局安装electron ,指定版本可electron@28.0.0(例如28.0.0版本)
npm install electron-packager -g //安装打包
npm install electron -g --force // 安装失败清楚缓存继续安装
npm cache clean --force //清楚npm缓存
安装依赖后,对打包项目进行配置
修改vue.config.js文件
module.exports = {
publicPath: './', // vue-cli3项目如果有该项配置,则将值修改为‘./’, 没有则添加
assetsPublicPath: './', // vue-cli2项目使用该配置项
}
tip:在vue.config.js文件内配置以下代码,解决electron+vue环境运行下出现__dirname is not defined报错解决方法
pluginOptions: {
electronBuilder: {
nodeIntegration: true,
}
},
3、安装完成后通过如下指令启动程序:
npm run electron:serve //运行项目
效果如下:
4、全局安装后你可以发现background.js文件,electron主进程的代码放在此文件内,渲染进程就交给vue
主进程 background.js文件
'use strict'
import { app, protocol, BrowserWindow ,ipcMain,nativeImage } from 'electron'
import { createProtocol } from 'vue-cli-plugin-electron-builder/lib'
import installExtension, { VUEJS_DEVTOOLS } from 'electron-devtools-installer'
const isDevelopment = process.env.NODE_ENV !== 'production'
const { exec } = require('child_process'); //获取打印机需要
let win;
// Scheme must be registered before the app is ready 计划必须在应用程序准备就绪之前注册
protocol.registerSchemesAsPrivileged([
{ scheme: 'app', privileges: { secure: true, standard: true } }
])
async function createWindow() {
// 创建浏览器窗口。
win = new BrowserWindow({
width: 1920,
height: 1080,
fullscreen: true,//全屏显示
webPreferences: {
//nodeIntegration: true,
//contextIsolation: false,
webSecurity:false, //允许跨域
nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION,
contextIsolation: !process.env.ELECTRON_NODE_INTEGRATION,
enableRemoteModule: true, // 需要启用remote模块shm
webviewTag: true, //开启webview //打印
}
})
win.webContents.openDevTools() //打开调试
console.log(process.env.WEBPACK_DEV_SERVER_URL,'process.env.WEBPACK_DEV_SERVER_URL');
if (process.env.WEBPACK_DEV_SERVER_URL) {
// 如果处于开发模式,则加载开发服务器的url
await win.loadURL(process.env.WEBPACK_DEV_SERVER_URL)
if (!process.env.IS_TEST) win.webContents.openDevTools()
} else {
createProtocol('app')
// 在非开发阶段加载index.html
win.loadURL('app://./index.html')//测试打包后地址
// win.loadURL('http://172.17.30.84:8090') //打包后访问url
}
}
// 获取打印机列表
ipcMain.on('get-printer-list', (event) => {
exec('wmic printer list brief', (err, stdout, stderr) => {
if (err) {
console.error('获取打印机列表时出错:', err);
event.reply('printer-list-reply', { error: err.message });
} else {
const printerList = stdout.trim().split('\r\n').slice(1); // 去除标题行
event.reply('printer-list-reply', { list: printerList });
}
});
});
// 打印功能
// 当渲染进程发送打印请求时
ipcMain.on('print-ticket-request', (event, ticketData) => {
const win = BrowserWindow.getFocusedWindow();
if (win) {
win.webContents.print({
silent: false, // 静默打印,不弹出打印对话框 false开启true关闭
printBackground: true, // 打印背景图形和颜色
scaleFactor: 2, // 增加这个值来放大内容
// margins:{
// marginType:"none",
// },
// pageRanges:[{from:1,to:0}],
// pageSize:'A4',
// 其他打印选项... 可看文档
}, (success, failureReason) => {
if (!success) {
console.error('Failed to print ticket:', failureReason);
// 可以通过 IPC 将错误信息发送回渲染进程
event.reply('print-ticket-reply', { success: false, error: failureReason });
} else {
console.log('Ticket printed successfully');
// 打印成功,可以通过 IPC 发送确认信息
event.reply('print-ticket-reply', { success: 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 (BrowserWindow.getAllWindows().length === 0) createWindow()
})
// 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 () => {
if (isDevelopment && !process.env.IS_TEST) {
// Install Vue Devtools
try {
await installExtension(VUEJS_DEVTOOLS)
} catch (e) {
console.error('Vue Devtools failed to install:', e.toString())
}
}
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()
})
}
}
5、打包命令:
npm run electron:build //打包
打包生成的文件在 dist_electron 文件夹,直接基于默认配置打包,生成的dist_electron 文件夹内容如下:
使用打印机打印
一、获取打印机列表
在主进程文件中添加以下代码
// 在 main.js 或 background.js 中
const { app, BrowserWindow, ipcMain } = require('electron');
const { exec } = require('child_process');
let mainWindow;
function createWindow() {
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true, // 允许在渲染进程中使用 Node.js
contextIsolation: false, // 禁用上下文隔离,以便可以直接访问 Node.js
},
});
mainWindow.loadFile('index.html');
}
// 获取打印机列表
ipcMain.on('get-printer-list', (event) => {
exec('wmic printer list brief', (err, stdout, stderr) => {
if (err) {
console.error('获取打印机列表时出错:', err);
event.reply('printer-list-reply', { error: err.message });
} else {
const printerList = stdout.trim().split('\r\n').slice(1); // 去除标题行
event.reply('printer-list-reply', { list: printerList });
}
});
});
app.whenReady().then(createWindow);
在渲染进程写入代码
import { ipcRenderer } from 'electron';
//在mounted内写下面代码
ipcRenderer.send('get-printer-list');
ipcRenderer.on('printer-list-reply', (event, { error, list }) => {
if (error) {
console.error('获取打印机列表时出错:', error);
} else {
console.log(list[2],'list获取打印机列表时成功');
}
});
二、打印功能
在主进程写入代码
// 当渲染进程发送打印请求时
ipcMain.on('print-ticket-request', (event, ticketData) => {
const win = BrowserWindow.getFocusedWindow();
if (win) {
win.webContents.print({
silent: false, // 静默打印,不弹出打印对话框 false开启true关闭
printBackground: true, // 打印背景图形和颜色
scaleFactor: 2, // 增加这个值来放大内容
// margins:{
// marginType:"none",
// },
// pageRanges:[{from:1,to:0}],
// pageSize:'A4',
// 其他打印选项...
}, (success, failureReason) => {
if (!success) {
console.error('Failed to print ticket:', failureReason);
// 可以通过 IPC 将错误信息发送回渲染进程
event.reply('print-ticket-reply', { success: false, error: failureReason });
} else {
console.log('Ticket printed successfully');
// 打印成功,可以通过 IPC 发送确认信息
event.reply('print-ticket-reply', { success: true });
}
});
}
});
渲染进程写
可以指定一个按钮点击打印实现
<div @click="handlePrint">打印</div>
import { ipcRenderer } from 'electron';
methods:{
handlePrint(){
const ticketData = { /* 你的小票数据 */ };
// 发送 IPC 请求到主进程以打印小票
ipcRenderer.send('print-ticket-request', );
// 监听回复,以处理打印结果
ipcRenderer.once('print-ticket-reply', (event, result) => {
if (result.success) {
console.log('小票打印成功');
} else {
console.error('小票打印失败:', result.error);
// 可以在这里添加错误处理逻辑
}
});
}
}
若想打印指定的内容可以根据调整 CSS 打印样式
@media print {
/* 隐藏所有不需要打印的元素 */
body * {
visibility: hidden;
}
/* 显示需要打印的图片容器 */
#print-container, #print-container * {
visibility: visible;
}
/* 添加其他打印样式,如页面边距、尺寸等 */
#print-container {
width: 100%;
height: auto;
page-break-after: always; /* 如果需要分页 */
}
}
先记录到这里,后续遇到问题继续记录!!!