Vue3项目-Electron构建桌面应用程序

一、创建Vue3项目

1、安装vue-cli
javascript 复制代码
npm i -g @vue/cli
 
#OR
 
yarn global add @vue/cli
2、创建vue项目(vue3)
javascript 复制代码
npm create vue@latest
3、创建完成后启动项目
javascript 复制代码
cd project_name && npm run dev

二、electron配置

1、安装electron
javascript 复制代码
npm install electron
2、安装vite-plugin-electron插件
javascript 复制代码
npm install vite-plugin-electron
3、添加electron配置文件(项目/electron/index.js)
javascript 复制代码
// -------------------------------<<模块导入>>-------------------------------
import { app, BrowserWindow, screen, ipcMain, Tray, Menu } from 'electron'
import path from 'path'
process.env['ELECTRON_DISABLE_SECURITY_WARNINGS'] = 'true'

// -------------------------------<<变量声明>>-------------------------------
// 定义全局变量,获取窗口实例
const windows = {
    // 主窗口
    main: {
        win: null
    },
}

const defaultMENU = 0x116; //当弹出系统菜单时

//托盘区图标
var appTray = null;

// -------------------------------<<函数定义>>-------------------------------
//禁用窗口自带的右键菜单
const disableContextMenu = (win) => {
    win.hookWindowMessage(defaultMENU, () => {
        win.setEnabled(false);
        setTimeout(() => {
            win.setEnabled(true);
        }, 20);
        return true;
    })
}

// 创建主窗口
const createWindow = () => {
    let {
        width,
        height
    } = screen.getPrimaryDisplay().workArea;
    windows.main.win = new BrowserWindow({
        width: width,
        height: height,
        show: true,
        frame: false,
        movable: true,
        resizable: true,
        webPreferences: {
            devTools: true,
            // 集成网页和 Node.js,也就是在渲染进程中,可以调用 Node.js 方法
            nodeIntegration: true,
            contextIsolation: false,
            webSecurity: false, //是否允许渲染进程访问本地文件
            //允许html页面上的javascript代码访问nodejs 环境api代码的能力(与node集成的意思)
        }
    })
    // 开发环境 development
    // 是生产环境 production
    if (process.env.NODE_ENV != 'development') {
        windows.main.win.loadFile(path.join(__dirname, "../index.html"));
    } else {
        windows.main.win.loadURL(`http://${process.env['VITE_DEV_SERVER_HOST']}:${process.env['VITE_DEV_SERVER_PORT']}` + "/index.html");
        if (!process.env.IS_TEST) windows.main.win.webContents.openDevTools();
    }
    disableContextMenu(windows.main.win);
}

// 系统托盘设置
const setTray = () => {
    //设置菜单内容
    let trayMenu = [{
        label: '退出', //菜单名称
        click: function () { //点击事件
            app.quit();
        }
    }];

    let trayIcon = null;
    //设置托盘区图标
    if (process.env.NODE_ENV != 'development') {
        trayIcon = path.join(__dirname, '../favicon.ico');
    } else {
        trayIcon = path.join(__dirname, '../../public/favicon.ico');
    }
    appTray = new Tray(trayIcon);
    //设置菜单
    const contextMenu = Menu.buildFromTemplate(trayMenu);
    //设置悬浮提示
    appTray.setToolTip('xxxxxxxxx');
    //设置
    appTray.setContextMenu(contextMenu);
    //点击图标
    appTray.on('click', function () {
        //显示主程序
        if (windows.main.win) windows.main.win.show();
    });
}

// 监听ipcMain请求
const listenIPC = () => {
    // 最小化
    ipcMain.on('min-app', () => {
        windows.main.win.minimize();
    });
    // 退出程序
    ipcMain.on('exit-app', () => {
        windows.main.win.close();
    })
}

// 初始化app(Electron初始化完成时触发)
app.whenReady().then(() => {
    createWindow();
    setTray();
    listenIPC()

    // app.on('activate', () => {
    //     if (BrowserWindow.getAllWindows().length === 0) createWindow()
    // })
});


app.on('window-all-closed', () => {
    if (process.platform !== 'darwin') app.quit()
})
4、vite.config.js配置
javascript 复制代码
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import electron from 'vite-plugin-electron'
import path, { resolve, join } from 'path'
export default defineConfig({
  plugins: [vue(), electron({
    main: {
      entry: "electron/index.js"
    }
  })],
  resolve: {
    alias: {
      "@": resolve(__dirname, 'src'), // 这里是将src目录配置别名为 @ 方便在项目中导入src目录下的文件
    }
  },
})
5、package.json配置
javascript 复制代码
{
  "name": "vite-project",
  "private": true,
  "version": "0.0.0",
  "main": "dist/electron/index.js", // 这里必须配置为dist/electron/index.js
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "vue": "^3.2.47",
    "@element-plus/icons-vue": "^2.1.0",
    "axios": "^1.3.4",
    "echarts": "^5.4.3",
    "element-plus": "^2.3.0",
    "pinia": "^2.1.7",
    "qs": "^6.11.1",
    "vue-draggable-resizable": "^2.3.0",
    "vue-router": "^4.2.4"
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^4.1.0",
    "electron": "^19.0.10",
    "vite": "^4.2.0",
    "vite-plugin-electron": "^0.8.3",
    "less": "^4.1.3",
    "less-loader": "^11.1.0"
  }
}

三、项目其他配置

1、main.js配置
javascript 复制代码
// 模块导入
import { createApp } from 'vue'
import App from './App.vue'
import router from './router/index'
import { createPinia } from "pinia";
import VueDraggableResizable from 'vue-draggable-resizable/src/components/vue-draggable-resizable.vue'
import 'vue-draggable-resizable/dist/VueDraggableResizable.css'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
import ModelAssembly from './components/common/ModelAssembly.vue';
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'

// 创建APP
const app = createApp(App);

// 创建Pinia
const pinia = createPinia();

//使el-input自动聚焦 所有页面都可使用 v-focus使用
app.directive('focus', {
    mounted: (el) => el.querySelector('input').focus()
})

// 注册全局组件
app.component('ModelAssembly', ModelAssembly)

//注册所有图标
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
    app.component(key, component) //注册组件图标
}

app.component('vue-draggable-resizable', VueDraggableResizable)
app.use(router);
app.use(pinia);
app.use(ElementPlus);
app.mount("#app");
2、pinia配置
javascript 复制代码
import { defineStore } from "pinia"
export const useIndexStore = defineStore('indexStore', {
    // 其它配置项
    state: () => {
        return {};
    },
    getters: {
    },
    actions: {
    }
})
3、router配置
javascript 复制代码
import { createRouter, createWebHashHistory } from 'vue-router';
const routes = [
    {
        path: '/', redirect: "/home"
    },
    {
        path: '/home',
        component: () => import('@/views/Home.vue'),
    },

];
const router = createRouter({
    history: createWebHashHistory(),
    routes
});
export default router;
相关推荐
xump9 分钟前
如何在DevTools选中调试一个实时交互才能显示的元素样式
前端·javascript·css
Front_Yue12 分钟前
深入探究跨域请求及其解决方案
前端·javascript
抱琴_14 分钟前
【Vue3】我用 Vue 封装了个 ECharts Hooks,同事看了直接拿去复用
前端·vue.js
风止何安啊15 分钟前
JS 里的 “变量租房记”:闭包是咋把变量 “扣” 下来的?
前端·javascript·node.js
老华带你飞17 分钟前
社区养老保障|智慧养老|基于springboot+小程序社区养老保障系统设计与实现(源码+数据库+文档)
java·数据库·vue.js·spring boot·小程序·毕设·社区养老保障
有点笨的蛋22 分钟前
深入理解 JavaScript 原型机制:构造函数、原型对象与原型链
前端·javascript
晴栀ay25 分钟前
JS中原型式面向对象的精髓
前端·javascript
3秒一个大25 分钟前
JavaScript 原型详解:从概念到实践
javascript
Amy_yang38 分钟前
js 封装时间格式化,将单位有秒(s)的数据转换为'00:00:00'格式
javascript
interception39 分钟前
爬虫js逆向,jsdom补环境,抖音,a_bogus
javascript·爬虫·python