Практический проект Vue + Electron

В этой главе мы будем использоватьVue + Electronдля создания приложения для заметок. Этот практический проект называетсяVueElectronNotes, а его функции охватывают многооконность, трей, файловые операции и IPC-взаимодействие. Это очень подходящий проект для практики начинающих.

Если вы ещё не знаете Vue, сначала можете обратиться к:Учебник по Vue。


I. Возможности проекта

  • Настольное приложение для заметок (Notes)
  • Главное окно отображает список заметок
  • Всплывает дочернее окно для создания новых заметок
  • Значок системного трея, сворачивание в трей
  • Локальное сохранение/чтение файлов
  • Безопасное взаимодействие между процессом рендеринга и главным процессом

II. Инициализация проекта

1. Создание проекта Vue

vue create VueElectronNotes
cd VueElectronNotes

Выберите пресет по умолчанию (Babel + ESLint).

2. Установите Electron и зависимости

npm install --save-dev electron electron-builder concurrently wait-on
npm install electron-store
  • electron-storeДля локального сохранения данных

III. Конфигурация главного процесса

electron-main.js:

Пример

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: 'Показать главное окно', click: () => mainWindow.show() },
    { label: 'Выход', click: () => app.Выход() }
  ])
  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)
})

Описание:

  • mainWindow: Главное окно, отображает список заметок
  • noteWindow: Дочернее окно, используется для создания новых заметок
  • Tray: Значок и меню в системном трее
  • ipcMain: Главный процесс получает сообщения от процесса рендеринга

4. Процесс рендеринга и Vue

preload.js:

Пример

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:

Пример

<template>
  <div>
    <h1>список заметок</h1>
    <button @click="openNoteWindow">Новая заметка</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', 'Новая заметка', '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:

Пример

<!DOCTYPE html>
<html>
  <head><meta charset="UTF-8"><title>Новая заметка</title></head>
  <body>
    <h2>Новая заметка</h2>
    <textarea id="note"></textarea><br>
    <button id="saveBtn">Сохранить</button>
    <script src="note.js"></script>
  </body>
</html>

note.js:

Пример

const saveBtn = document.getElementById('saveBtn')
saveBtn.addEventListener('click', () => {
  const note = document.getElementById('note').value
  if (note) {
    window.electronAPI.saveNote(note)
    window.close()
  }
})

Описание:

  • note.htmlэто всплывающее окно для ввода заметок
  • note.jsВызовelectronAPI.saveNoteОтправить в главный процесс
  • Главное окно получит егоupdate-notesСообщение обновляет список

V. Запуск проекта

Режим разработки:

npm run electron:serve
  • Запуск Vue Dev Server + Electron одновременно
  • Возможность отладки UI в реальном времени

Упаковка приложения:

npm run electron:build
  • Вывод исполняемого файла вdist_electron
  • Поддерживает Windows/macOS/Linux
Другие расширения