In this chapter, we will use **Vue + Electron** to create a notes application. This practical project is called **VueElectronNotes**, with features including multi-window, system tray, file operations, and IPC communication, making it a very suitable project for beginners to practice.
If you are not familiar with Vue, you can refer to: (#).
* * *
## 1. Project Features
* Desktop Notes Application (Notes)
* Main window displays notes list
* New note opens a child window
* System tray icon, minimize to tray
* File local save/read
* Secure communication between renderer and main process
* * *
## 2. Project Initialization
### 1. Create Vue Project
vue create VueElectronNotes cd VueElectronNotes
Select the default preset (Babel + ESLint).
### 2. Install Electron and Dependencies
npm install --save-dev electron electron-builder concurrently wait-on npm install electron-store
* `electron-store` is used for local data persistence
* * *
## 3. Main Process Configuration
### electron-main.js:
## Example
const{ app, BrowserWindow, Tray, Menu, ipcMain }= require('electron')
const path = require('path')
const Store = require('electron-store')
let mainWindow, noteWindow, tray
const store =new Store()
function createMainWindow(){
mainWindow =new BrowserWindow({
width:800,
height:600,
webPreferences:{
preload: path.join(__dirname,'preload.js'),
contextIsolation:true,
nodeIntegration:false
}
})
if(process.env.NODE_ENV==='development'){
mainWindow.loadURL('http://localhost:8080')
}else{
mainWindow.loadFile('dist/index.html')
}
mainWindow.on('minimize',(e)=>{
e.preventDefault()
mainWindow.hide()
})
createTray()
}
function createNoteWindow(){
noteWindow =new BrowserWindow({
width:400,
height:300,
parent: mainWindow,
modal:true,
webPreferences:{
preload: path.join(__dirname,'preload.js'),
contextIsolation:true,
nodeIntegration:false
}
})
noteWindow.loadFile('note.html')
}
function createTray(){
tray =new Tray(path.join(__dirname,'assets/icon.png'))
const contextMenu = Menu.buildFromTemplate([
{ label:'Display main window', click:()=> mainWindow.show()},
{ label:'Exit', click:()=> app.quit()}
])
tray.setToolTip('VueElectronNotes')
tray.setContextMenu(contextMenu)
}
app.whenReady().then(createMainWindow)
app.on('window-all-closed',()=>{
if(process.platform!=='darwin') app.quit()
})
ipcMain.handle('get-notes',()=>{
return store.get('notes',[])
})
ipcMain.on('save-note',(event, note)=>{
const notes = store.get('notes',[])
notes.push(note)
store.set('notes', notes)
mainWindow.webContents.send('update-notes', notes)
})
**Description:**
* `mainWindow`: Main window, displays notes list
* `noteWindow`: Child window, for creating new notes
* `Tray`: System tray icon and menu
* `ipcMain`: Main process receives messages from renderer process
* * *
## 4. Renderer Process and Vue
### `preload.js`:
## Example
const{ contextBridge, ipcRenderer }= require('electron')
contextBridge.exposeInMainWorld('electronAPI',{
getNotes:()=> ipcRenderer.invoke('get-notes'),
saveNote:(note)=> ipcRenderer.send('save-note', note),
onUpdateNotes:(callback)=> ipcRenderer.on('update-notes', callback)
})
### `src/App.vue`:
## Example
`note.js`:
## Example
const saveBtn = document.getElementById('saveBtn')
saveBtn.addEventListener('click',()=>{
const note = document.getElementById('note').value
if(note){
window.electronAPI.saveNote(note)
window.close()
}
})
**Description:**
* `note.html` is the popup window for entering notes
* `note.js` calls `electronAPI.saveNote` to send to the main process
* The main window will receive the `update-notes` message to update the list
* * *
## 5. Running the Project
### Development Mode:
npm run electron:serve
* Vue Dev Server + Electron start simultaneously
* Real-time UI debugging available
### Build Application:
npm run electron:build
* Output executable file to `dist_electron`
* Supports Windows/macOS/Linux