Projet pratique Vue + Electron
Dans ce chapitre, nous allons utiliserVue + Electronpour créer une application de prise de notes. Ce projet pratique s'appelleVueElectronNotes, avec des fonctionnalités couvrant le multi-fenêtres, la barre d'état système, les opérations sur les fichiers et la communication IPC. C'est un projet très adapté aux débutants pour s'exercer.
Si vous ne connaissez pas encore Vue, vous pouvez d'abord consulter :Tutoriel Vue。
I. Fonctionnalités du projet
- Application de prise de notes pour bureau (Notes)
- La fenêtre principale affiche la liste des notes
- Une fenêtre enfant s'ouvre pour créer de nouvelles notes
- Icône de la barre d'état système, réduire dans la barre d'état système
- Enregistrement/lecture de fichiers locaux
- Communication sécurisée entre le processus de rendu et le processus principal
II. Initialisation du projet
1. Créer un projet Vue
vue create VueElectronNotes cd VueElectronNotes
Sélectionner le preset par défaut (Babel + ESLint).
2. Installer Electron et les dépendances
npm install --save-dev electron electron-builder concurrently wait-on npm install electron-store
electron-storePour la persistance locale des données
III. Configuration du processus principal
electron-main.js:
Exemple
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: 'Afficher la fenêtre principale', click: () => mainWindow.show() },
{ label: 'Quitter', 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)
})
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: 'Afficher la fenêtre principale', click: () => mainWindow.show() },
{ label: 'Quitter', 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: Fenêtre principale, affiche la liste des notesnoteWindow: Fenêtre enfant, utilisée pour créer de nouvelles notesTray: Icône et menu de la zone de notificationipcMain: Le processus principal reçoit des messages du processus de rendu
4. Processus de rendu et Vue
preload.js:
Exemple
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)
})
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:
Exemple
<template>
<div>
<h1>liste de notes</h1>
<button @click="openNoteWindow">Nouvelle note</button>
<ul>
<li v-for="(note, index) in notes" :key="index">{{ note }}</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return { notes: [] }
},
methods: {
openNoteWindow() {
window.open('note.html', 'New Note', 'width=400,height=300')
}
},
mounted() {
window.electronAPI.getNotes().then((notes) => {
this.notes = notes
})
window.electronAPI.onUpdateNotes((event, notes) => {
this.notes = notes
})
}
}
</script>
<div>
<h1>liste de notes</h1>
<button @click="openNoteWindow">Nouvelle note</button>
<ul>
<li v-for="(note, index) in notes" :key="index">{{ note }}</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return { notes: [] }
},
methods: {
openNoteWindow() {
window.open('note.html', 'New Note', 'width=400,height=300')
}
},
mounted() {
window.electronAPI.getNotes().then((notes) => {
this.notes = notes
})
window.electronAPI.onUpdateNotes((event, notes) => {
this.notes = notes
})
}
}
</script>
note.html + note.js:
note.html:
Exemple
<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>Nouvelle note</title></head>
<body>
<h2>Nouvelle note</h2>
<textarea id="note"></textarea><br>
<button id="saveBtn">Enregistrer</button>
<script src="note.js"></script>
</body>
</html>
<html>
<head><meta charset="UTF-8"><title>Nouvelle note</title></head>
<body>
<h2>Nouvelle note</h2>
<textarea id="note"></textarea><br>
<button id="saveBtn">Enregistrer</button>
<script src="note.js"></script>
</body>
</html>
note.js:
Exemple
const saveBtn = document.getElementById('saveBtn')
saveBtn.addEventListener('click', () => {
const note = document.getElementById('note').value
if (note) {
window.electronAPI.saveNote(note)
window.close()
}
})
saveBtn.addEventListener('click', () => {
const note = document.getElementById('note').value
if (note) {
window.electronAPI.saveNote(note)
window.close()
}
})
Description:
note.htmlest une fenêtre pop-up pour saisir des notesnote.jsAppelelectronAPI.saveNoteEnvoyer au processus principal- La fenêtre principale le recevra
update-notesLe message met à jour la liste
V. Exécuter le projet
Mode développement :
npm run electron:serve
- Démarrer Vue Dev Server + Electron simultanément
- Peut déboguer l'interface utilisateur en temps réel
Empaquetage de l'application :
npm run electron:build
- Générer le fichier exécutable vers
dist_electron - Prend en charge Windows/macOS/Linux