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;
相关推荐
Sheldon一蓑烟雨任平生5 小时前
Vue3 插件(可选独立模块复用)
vue.js·vue3·插件·vue3 插件·可选独立模块·插件使用方式·插件中的依赖注入
鱼与宇6 小时前
苍穹外卖-VUE
前端·javascript·vue.js
用户47949283569157 小时前
Safari 中文输入法的诡异 Bug:为什么输入 @ 会变成 @@? ## 开头 做 @ 提及功能的时候,测试同学用 Safari 测出了个奇怪的问题
前端·javascript·浏览器
裴嘉靖7 小时前
Vue 生成 PDF 完整教程
前端·vue.js·pdf
毕设小屋vx ylw2824267 小时前
Java开发、Java Web应用、前端技术及Vue项目
java·前端·vue.js
冴羽8 小时前
今日苹果 App Store 前端源码泄露,赶紧 fork 一份看看
前端·javascript·typescript
蒜香拿铁8 小时前
Angular【router路由】
前端·javascript·angular.js
时间的情敌8 小时前
Vite 大型项目优化方案
vue.js
西洼工作室9 小时前
高效管理搜索历史:Vue持久化实践
前端·javascript·vue.js
樱花开了几轉9 小时前
element ui下拉框踩坑
开发语言·javascript·ui