Недавно я задумал переписать свое приложение Electron «Scrum Daily Standup Picker» на Vue 3. Первоначальный релиз я написал на Angular, но я хотел провести рефакторинг кодовой базы и переписать его на Vue 3.
Почему? Потому что я люблю Vue и хочу иметь публичную витрину, на которую я могу ссылаться потенциальным клиентам.
Почему Quasar?
Quasar — это лицензированный MIT фреймворк на базе Vue.js с открытым исходным кодом, который предназначен для создания SPA, SSR, PWA, мобильных приложений, десктопных приложений и браузерных расширений, используя одну кодовую базу. Он обрабатывает настройку сборки и предоставляет полную коллекцию UI-компонентов, соответствующих Material Design.
Девиз Quasar таков:
Напишите код один раз и одновременно разверните его как веб-сайт, мобильное приложение и/или электронное приложение.
Использование Quasar значительно экономит время разработки по этим причинам:
- Он основан на Vue.js.
- Он предоставляет множество компонентов пользовательского интерфейса, которые следуют рекомендациям Material Design.
- Регулярный цикл выпуска новых версий, включающий новые функции.
- Он обеспечивает поддержку каждого режима сборки (SPA, SSR, PWA, мобильное приложение, настольное приложение и расширение для браузера).
- У него есть собственный CLI, который обеспечивает приятный опыт разработчика. Например, мы можем собрать наше приложение как SPA, мобильное или настольное приложение в одной папке проекта.
Читайте подробнее о том, почему Quasar может быть хорошим выбором для вашего следующего проекта.
Установка Quasar CLI
Исходный код следующей демонстрации доступен на GitHub
# Node.js >=12.22.1 is required.
$ yarn global add @quasar/cli
# or
$ npm install -g @quasar/cli
Давайте начнем с создания нового проекта с помощью Quasar CLI:
▶ quasar create vue3-electron-demo
___
/ _ _ _ ______ ___ ___
| | | | | | |/ _` / __|/ _` | '__ |
| |_| | |_| | (_| __ (_| | |
___\__ ,_| __,_|___ /__,_|_|
? Project name (internal usage for dev) vue3-electron-demo
? Project product name (must start with letter if building mobile apps) Quasar App
? Project description A Quasar Framework app
? Author Michael Hoffmann <michael.hoffmann@mokkapps.de>
? Pick your CSS preprocessor: SCSS
? Check the features needed for your project: ESLint (recommended), TypeScript
? Pick a component style: Composition
? Pick an ESLint preset: Prettier
? Continue to install project dependencies after the project has been created? (recommended) NPM
Мы выбрали SCSS в качестве нашего CSS-препроцессора, ESLint & Typescript в качестве дополнительных функций, Vue 3’s Composition API и Prettier для форматирования кода.
Не выбирайте Vuex, поскольку мы добавим другую библиотеку состояний в следующей главе. Если вы случайно добавили Vuex, удалите его вручную из вашего package.json
.
Прочитайте официальную документацию для получения дополнительной информации о Quasar CLI.
Добавьте Pinia в качестве библиотеки магазина Vue
Мы будем использовать Pinia в качестве библиотеки магазина Vue, которая в настоящее время является рекомендуемой библиотекой состояния для Vue.
Сначала нам нужно установить Pinia:
yarn add pinia
# or with npm
npm install pinia
Чтобы иметь возможность зарегистрировать Pinia в нашем экземпляре приложения Vue, нам нужно создать загрузочный файл Quasar:
Частым случаем использования Quasar-приложений является запуск кода до инстанцирования корневого экземпляра приложения Vue, например, внедрение и инициализация собственных зависимостей (примеры: компоненты Vue, библиотеки…) или просто настройка некоторого стартового кода вашего приложения.
Наш загрузочный файл называется pinia.ts
и находится по адресу src/boot
:
import { boot } from 'quasar/wrappers';
import { createPinia } from 'pinia';
export default boot(({ app }) => {
app.use(createPinia());
});
Нам также нужно добавить этот новый файл в quasar.conf.js
:
module.exports = configure(function (ctx) {
return {
...
// app boot file (/src/boot)
// --> boot files are part of "main.js"
// https://quasar.dev/quasar-cli/boot-files
boot: ['pinia'], ...
}
}
Теперь мы можем создать новую папку pinia
в src
.
Мы не можем назвать эту папку store
, так как это имя зарезервировано для официальной интеграции Vuex.
Базовый магазин может выглядеть следующим образом:
import { defineStore } from 'pinia';
// useStore could be anything like useUser, useCart
// the first argument is a unique id of the store across your application
const useStore = defineStore('storeId', {
state: () => {
return {
counter: 0,
lastName: 'Michael',
firstName: 'Michael',
};
},
getters: {
fullName: state => `${state.firstName} ${state.lastName}`,
},
actions: {
increment() {
this.counter++;
},
},
});
export default useStore;
Мы можем использовать этот магазин в любом компоненте Vue:
<template>Counter: {{ store.counter }}</template>
<script setup lang="ts">
import { useStore } from '@/stores/counter';
const store = useStore();
</script>
Теперь мы можем запустить приложение Vue с помощью Quasar CLI:
quasar dev
Приложение Vue обслуживается по адресу http://localhost:8080
:
Quasar Dev Mode
Настройка Electron
Прочитайте это введение, если вы новичок в Electron.
Для разработки/сборки приложения Quasar Electron нам необходимо добавить режим Electron в наш проект Quasar:
$ quasar mode add electron
Каждое приложение Electron имеет два потока: основной поток (занимается окном и кодом инициализации — из недавно созданной папки /src-electron
) и поток рендеринга (который занимается фактическим содержимым вашего приложения из /src
).
Новая папка имеет следующую структуру:
.
└── src-electron/
├── icons/ # Icons of your app for all platforms
| ├── icon.icns # Icon file for Darwin (MacOS) platform
| ├── icon.ico # Icon file for win32 (Windows) platform
| └── icon.png # Tray icon file for all platforms
├── electron-preload.js # (or .ts) Electron preload script (injects Node.js stuff into renderer thread)
└── electron-main.js # (or .ts) Main thread code
Теперь мы готовы запустить наше приложение Electron:
$ quasar dev -m electron
Эта команда откроет окно Electron, в котором будет отображаться ваше приложение вместе с инструментами разработчика, открытыми бок о бок:
Quasar Electron Dev
Читайте официальную документацию для получения дополнительной и подробной информации о разработке приложений Electron с помощью Quasar.
Управление Electron из кода Vue
Если мы хотим использовать функции Electron, такие как открытие диалога с файлами, нам нужно написать некоторый код, чтобы иметь доступ к API Electron.
Например, если мы хотим показать диалог для открытия файлов, Electron предоставляет API для отображения диалогов системы для открытия и сохранения файлов, оповещения и т.д.
Сначала нам нужно установить @electron/remote
:
npm install -D @electron/remote
Затем нам нужно изменить src-electron/electron-main.js
и инициализировать @electron/remote
:
import { app, BrowserWindow, nativeTheme } from 'electron'
import { initialize, enable } from '@electron/remote/main'import path from 'path'
import os from 'os'
initialize();
let mainWindow;
function createWindow () {
/**
* Initial window options
*/
mainWindow = new BrowserWindow({
icon: path.resolve(__dirname, 'icons/icon.png'), // tray icon
width: 1000,
height: 600,
useContentSize: true,
webPreferences: {
contextIsolation: true,
// More info: /quasar-cli/developing-electron-apps/electron-preload-script
preload: path.resolve(__dirname, process.env.QUASAR_ELECTRON_PRELOAD)
}
})
// ....
enable(mainWindow.webContents);}
Если мы хотим использовать Electron API из нашего кода Vue, нам нужно добавить некоторый код в src-electron/electron-preload.js
:
import { contextBridge } from 'electron';
import { dialog } from '@electron/remote';
// 'electronApi' will be available on the global window context
contextBridge.exposeInMainWorld('electronApi', {
openFileDialog: async (title, folder, filters) => {
// calling showOpenDialog from Electron API: https://www.electronjs.org/docs/latest/api/dialog/
const response = await dialog.showOpenDialog({ title, filters, properties: ['openFile', 'multiSelections'], }); return response.filePaths;
}
});
Далее мы создадим src/api/electron-api.ts
для доступа к этому коду из нашего приложения Vue:
export interface ElectronFileFilter {
name: string;
extensions: string[];
}
export interface ElectronApi {
openFileDialog: (
title: string,
folder: string,
filters: ElectronFileFilter
) => Promise<string[]>;
}
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
export const electronApi: ElectronApi = (window as { electronApi: ElectronApi })
.electronApi;
Теперь мы можем использовать этот API в любом месте нашего компонента Vue:
<template>
<q-btn @click="openElectronFileDialog">Open Electron File Dialog</q-btn>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { electronApi } from 'src/api/electron-api';
export default defineComponent({
name: 'PageIndex',
components: { },
setup() {
const openElectronFileDialog = async () => {
return electronApi.openFileDialog('Test', 'folder', { name: 'images', extensions: ['jpg'] });
};
return { openElectronFileDialog };
},
});
</script>
Нажатие на кнопку теперь должно открыть диалог файлов родной ОС:
Electron File Dialog
Заключение
Quasar позволяет нам быстро разрабатывать настольные приложения Electron на Vue с высококачественными компонентами пользовательского интерфейса, которые следуют рекомендациям Material Design.
Наиболее значительным преимуществом по сравнению с пользовательским проектом Electron + Vue из GitHub является то, что Quasar имеет регулярный цикл выпуска и предоставляет руководства по обновлению старых версий.
Посмотрите на мой GitHub-репозиторий «Scrum Daily Standup Picker», чтобы увидеть более сложный проект «Quasar-Electron-Vue3-Typescript-Pinia». Исходный код следующей демонстрации доступен на GitHub.
Если вам понравилась эта статья, следуйте за мной в Twitter, чтобы получать уведомления о новых статьях блога и других материалах от меня.
Также (или дополнительно) вы можете подписаться на мою рассылку.