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;
相关推荐
杨荧几秒前
【JAVA毕业设计】基于Vue和SpringBoot的服装商城系统学科竞赛管理系统
java·开发语言·vue.js·spring boot·spring cloud·java-ee·kafka
minDuck3 分钟前
ruoyi-vue集成tianai-captcha验证码
java·前端·vue.js
小政爱学习!23 分钟前
封装axios、环境变量、api解耦、解决跨域、全局组件注入
开发语言·前端·javascript
魏大帅。28 分钟前
Axios 的 responseType 属性详解及 Blob 与 ArrayBuffer 解析
前端·javascript·ajax
花花鱼35 分钟前
vue3 基于element-plus进行的一个可拖动改变导航与内容区域大小的简单方法
前端·javascript·elementui
k093338 分钟前
sourceTree回滚版本到某次提交
开发语言·前端·javascript
web行路人1 小时前
React中类组件和函数组件的理解和区别
前端·javascript·react.js·前端框架
番茄小酱0011 小时前
Expo|ReactNative 中实现扫描二维码功能
javascript·react native·react.js
子非鱼9211 小时前
【Ajax】跨域
javascript·ajax·cors·jsonp
超雄代码狂2 小时前
ajax关于axios库的运用小案例
前端·javascript·ajax