├── demo.png ├── babel.config.js ├── public ├── favicon.ico └── index.html ├── src ├── assets │ ├── logo.png │ └── mine.png ├── main.js ├── App.vue ├── views │ ├── home.vue │ ├── image.vue │ └── about.vue ├── router │ └── index.js ├── components │ └── ImageList.vue └── background.js ├── .gitignore ├── README.md ├── vue.config.js └── package.json /demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunniejs/electron-vue-cli3-demo/HEAD/demo.png -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/app' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunniejs/electron-vue-cli3-demo/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunniejs/electron-vue-cli3-demo/HEAD/src/assets/logo.png -------------------------------------------------------------------------------- /src/assets/mine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunniejs/electron-vue-cli3-demo/HEAD/src/assets/mine.png -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | import router from './router' 4 | Vue.config.productionTip = false 5 | 6 | new Vue({ 7 | router, 8 | render: h => h(App) 9 | }).$mount('#app') 10 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 14 | 15 | 17 | -------------------------------------------------------------------------------- /src/views/home.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw? 22 | 23 | #Electron-builder output 24 | /dist_electron -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # electron-vue-example 2 | 3 | 从零开始搭建,基于 electron vue cli3 的桌面应用。[项目介绍](https://juejin.im/post/5d0af5d2f265da1b614ffd72). 4 | 5 | ## 如何运行实例 6 | 7 | ``` 8 | // 克隆 9 | git clone https://github.com/sunniejs/electron-vue-cli3-demo.git 10 | // 安装依赖 11 | npm install 12 | // 运用 13 | electron:serve 14 | 15 | ``` 16 | 17 | ## 截图 18 | 19 | ![demo](./demo.png) 20 | -------------------------------------------------------------------------------- /src/views/image.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 24 | 25 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/views/about.vue: -------------------------------------------------------------------------------- 1 | 9 | 21 | 28 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | electron-vue-example 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /vue.config.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const path = require('path') 3 | 4 | function resolve(dir) { 5 | return path.join(__dirname, dir) 6 | } 7 | // const name = 'electron-vue-example' // page title 8 | const port = 9020 9 | module.exports = { 10 | // publicPath: '/', 11 | // outputDir: 'dist', 12 | // assetsDir: 'static', 13 | // lintOnSave: process.env.NODE_ENV === 'development', 14 | // productionSourceMap: false, 15 | devServer: { 16 | port: port 17 | // open: true, 18 | // overlay: { 19 | // warnings: false, 20 | // errors: true 21 | // } 22 | }, 23 | chainWebpack(config) { 24 | // alias 25 | config.resolve.alias.set('@', resolve('src')) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/router/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Router from 'vue-router' 3 | 4 | Vue.use(Router) 5 | 6 | export const constantRouterMap = [ 7 | { 8 | path: '/', 9 | redirect: '/home' 10 | }, 11 | { 12 | path: '/home', 13 | name: 'home', 14 | component: () => import('@/views/home') 15 | }, 16 | { 17 | path: '/image', 18 | name: 'image', 19 | component: () => import('@/views/image.vue') 20 | }, 21 | { 22 | path: '/about', 23 | name: 'about', 24 | component: () => import('@/views/about.vue') 25 | } 26 | ] 27 | const router = new Router({ 28 | // mode: 'history', // require service support 29 | base: process.env.BASE_URL, 30 | scrollBehavior: () => ({ y: 0 }), 31 | routes: constantRouterMap 32 | }) 33 | 34 | export default router 35 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "electron-vue-example", 3 | "version": "0.1.0", 4 | "description": "Electron vue cli3 demo ", 5 | "author": "Sunnie", 6 | "private": true, 7 | "scripts": { 8 | "serve": "vue-cli-service serve", 9 | "build": "vue-cli-service build", 10 | "lint": "vue-cli-service lint", 11 | "electron:build": "vue-cli-service electron:build", 12 | "electron:serve": "vue-cli-service electron:serve", 13 | "postinstall": "electron-builder install-app-deps", 14 | "postuninstall": "electron-builder install-app-deps" 15 | }, 16 | "main": "background.js", 17 | "dependencies": { 18 | "axios": "^0.19.0", 19 | "core-js": "^2.6.5", 20 | "vue": "^2.6.10", 21 | "vue-router": "^3.0.6" 22 | }, 23 | "devDependencies": { 24 | "@vue/cli-plugin-babel": "^3.8.0", 25 | "@vue/cli-plugin-eslint": "^3.8.0", 26 | "@vue/cli-service": "^3.8.0", 27 | "babel-eslint": "^10.0.1", 28 | "electron": "^5.0.0", 29 | "eslint": "^5.16.0", 30 | "eslint-plugin-vue": "^5.0.0", 31 | "vue-cli-plugin-electron-builder": "^1.3.4", 32 | "vue-template-compiler": "^2.6.10" 33 | }, 34 | "eslintConfig": { 35 | "root": true, 36 | "env": { 37 | "node": true 38 | }, 39 | "extends": [ 40 | "plugin:vue/essential", 41 | "eslint:recommended" 42 | ], 43 | "rules": {}, 44 | "parserOptions": { 45 | "parser": "babel-eslint" 46 | } 47 | }, 48 | "postcss": { 49 | "plugins": { 50 | "autoprefixer": {} 51 | } 52 | }, 53 | "browserslist": [ 54 | "> 1%", 55 | "last 2 versions" 56 | ] 57 | } -------------------------------------------------------------------------------- /src/components/ImageList.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 78 | 79 | 80 | 144 | -------------------------------------------------------------------------------- /src/background.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | import { app, protocol, BrowserWindow, ipcMain } from 'electron' 4 | import { createProtocol, installVueDevtools } from 'vue-cli-plugin-electron-builder/lib' 5 | const isDevelopment = process.env.NODE_ENV !== 'production' 6 | 7 | // Keep a global reference of the window object, if you don't, the window will 8 | // be closed automatically when the JavaScript object is garbage collected. 9 | let win 10 | // 添加一个imageWindow 11 | let imageWindow 12 | let aboutWindow 13 | 14 | // Scheme must be registered before the app is ready 15 | protocol.registerSchemesAsPrivileged([{ scheme: 'app', privileges: { secure: true, standard: true } }]) 16 | 17 | function createWindow() { 18 | // Create the browser window. 19 | win = new BrowserWindow({ 20 | width: 800, 21 | height: 600, 22 | webPreferences: { 23 | nodeIntegration: true 24 | } 25 | }) 26 | imageWindow = new BrowserWindow({ 27 | width: 400, 28 | height: 400, 29 | parent: win, 30 | show: false, 31 | webPreferences: { 32 | nodeIntegration: true 33 | } 34 | }) 35 | aboutWindow = new BrowserWindow({ 36 | width: 500, 37 | height: 500, 38 | parent: win, 39 | show: false, 40 | webPreferences: { 41 | nodeIntegration: true 42 | } 43 | }) 44 | 45 | if (process.env.WEBPACK_DEV_SERVER_URL) { 46 | // Load the url of the dev server if in development mode 47 | win.loadURL(process.env.WEBPACK_DEV_SERVER_URL) 48 | imageWindow.loadURL(process.env.WEBPACK_DEV_SERVER_URL + '/#/image') 49 | aboutWindow.loadURL(process.env.WEBPACK_DEV_SERVER_URL + '/#/about') 50 | if (!process.env.IS_TEST) win.webContents.openDevTools() 51 | } else { 52 | createProtocol('app') 53 | // Load the index.html when not in development 54 | win.loadURL('app://./index.html') 55 | } 56 | 57 | win.on('closed', () => { 58 | win = null 59 | }) 60 | imageWindow.on('close', e => { 61 | e.preventDefault() 62 | imageWindow.hide() 63 | }) 64 | aboutWindow.on('close', e => { 65 | e.preventDefault() 66 | aboutWindow.hide() 67 | }) 68 | } 69 | 70 | // Quit when all windows are closed. 71 | app.on('window-all-closed', () => { 72 | // On macOS it is common for applications and their menu bar 73 | // to stay active until the user quits explicitly with Cmd + Q 74 | if (process.platform !== 'darwin') { 75 | app.quit() 76 | } 77 | }) 78 | 79 | app.on('activate', () => { 80 | // On macOS it's common to re-create a window in the app when the 81 | // dock icon is clicked and there are no other windows open. 82 | if (win === null) { 83 | createWindow() 84 | } 85 | }) 86 | 87 | // This method will be called when Electron has finished 88 | // initialization and is ready to create browser windows. 89 | // Some APIs can only be used after this event occurs. 90 | app.on('ready', async () => { 91 | if (isDevelopment && !process.env.IS_TEST) { 92 | // Install Vue Devtools 93 | try { 94 | await installVueDevtools() 95 | } catch (e) { 96 | console.error('Vue Devtools failed to install:', e.toString()) 97 | } 98 | } 99 | createWindow() 100 | }) 101 | 102 | // Exit cleanly on request from parent process in development mode. 103 | if (isDevelopment) { 104 | if (process.platform === 'win32') { 105 | process.on('message', data => { 106 | if (data === 'graceful-exit') { 107 | app.quit() 108 | } 109 | }) 110 | } else { 111 | process.on('SIGTERM', () => { 112 | app.quit() 113 | }) 114 | } 115 | } 116 | //ipcMain 模块有如下监听事件方法: 117 | // 监听 组件@/compontents/ImageList.vue methods:openImage下的ipcRenderer.send("toggle-image", image) 118 | // render 发送消息,main 接收消息 119 | // 120 | ipcMain.on('toggle-image', (event, arg) => { 121 | imageWindow.show() 122 | // 拿到消息后再发送给@/views/image.vue中的 ipcRenderer.on('image'... 123 | imageWindow.webContents.send('image', arg) 124 | }) 125 | 126 | ipcMain.on('toggle-about', (event, arg) => { 127 | aboutWindow.show() 128 | }) 129 | --------------------------------------------------------------------------------