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;
相关推荐
真的很上进2 小时前
如何借助 Babel+TS+ESLint 构建现代 JS 工程环境?
java·前端·javascript·css·react.js·vue·html
web130933203982 小时前
vue elementUI form组件动态添加el-form-item并且动态添加rules必填项校验方法
前端·vue.js·elementui
supermapsupport4 小时前
iClient3D for Cesium在Vue中快速实现场景卷帘
前端·vue.js·3d·cesium·supermap
m0_748254884 小时前
vue+elementui实现下拉表格多选+搜索+分页+回显+全选2.0
前端·vue.js·elementui
噢,我明白了5 小时前
同源策略:为什么XMLHttpRequest不能跨域请求资源?
javascript·跨域
sanguine__5 小时前
APIs-day2
javascript·css·css3
苹果醋35 小时前
Golang的文件加密工具
运维·vue.js·spring boot·nginx·课程设计
关你西红柿子6 小时前
小程序app封装公用顶部筛选区uv-drop-down
前端·javascript·vue.js·小程序·uv
济南小草根6 小时前
把一个Vue项目的页面打包后再另一个项目中使用
前端·javascript·vue.js
小木_.6 小时前
【python 逆向分析某有道翻译】分析有道翻译公开的密文内容,webpack类型,全程扣代码,最后实现接口调用翻译,仅供学习参考
javascript·python·学习·webpack·分享·逆向分析