使用 Pinia、Electron 和 Quasar 构建 Vue 3 桌面应用程序
最近,我计划在 Vue 3 中重写我的“Scrum Daily Standup Picker” Electron 应用程序。我在 Angular 中编写了初始版本,但我想重构代码库并在 Vue 3 中重写。
为什么?因为我喜欢 Vue,并希望有一个公开展示,我可以参考潜在客户。
为什么是类星体?
Quasar是 MIT 许可的基于 Vue.js 的开源框架,针对 SPA、SSR、PWA、移动应用程序、桌面应用程序和浏览器扩展程序,所有这些都使用一个代码库。它处理构建设置并提供符合 Material Design 的 UI 组件的完整集合。
Quasar的座右铭是:
编写一次代码,同时将其部署为网站、移动应用程序和/或电子应用程序。
由于以下原因,使用 Quasar 可以大大节省开发时间:
-
它基于 Vue.js。
-
它提供了许多遵循 Material Design 准则的 UI 组件。
-
它有一个包含新功能的定期发布周期。
-
它为每种构建模式(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 的 Composition API和1004047 Prettier 60 10 代码格式化。
不要选择 Vuex,因为我们将在下一章添加另一个状态库。如果您不小心添加了 Vuex,请从package.json中手动将其删除。
阅读官方文档了解有关 Quasar CLI 的更多信息。
添加Pineapple 作为View Store Library
我们将使用Pinia作为 Vue 存储库,它现在是 Vue 的推荐状态库。
首先,我们需要安装 Pinia:
yarn add pinia
# or with npm
npm install pinia
进入全屏模式 退出全屏模式
为了能够在我们的 Vue 应用程序实例中注册 Pinia,我们需要创建一个Quasar Boot File:
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'], ...
}
}
进入全屏模式 退出全屏模式
现在,我们可以在src中创建一个名为pinia的新文件夹。
我们不能将此文件夹命名为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 组件中使用这个 store:
<template>Counter: {{ store.counter }}</template>
<script setup lang="ts">
import { useStore } from '@/stores/counter';
const store = useStore();
</script>
进入全屏模式 退出全屏模式
现在我们可以使用 Quasar CLI 运行 Vue 应用程序:
quasar dev
进入全屏模式 退出全屏模式
Vue 应用程序在http://localhost:8080提供服务:

Quasar 开发模式
设置电子
如果您是 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
阅读官方文档以获取有关使用 Quasar 开发 Electron 应用程序的更多详细信息。
来自 Vue 代码的控制电子
如果我们想使用 Electron 的功能,比如打开文件对话框,我们需要编写一些代码来访问 Electron 的 API。
例如,如果我们想显示一个打开文件的对话框,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);}
进入全屏模式 退出全屏模式
如果我们想在 Vue 代码中使用 Electron API,我们需要在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;
进入全屏模式 退出全屏模式
现在我们可以在 Vue 组件的任何地方使用这个 API:
<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>
进入全屏模式 退出全屏模式
单击该按钮现在应该打开本机操作系统文件对话框:

电子文件对话框
结论
Quasar 使我们能够使用遵循 Material Design 准则的高质量 UI 组件在 Vue 中快速开发 Electron 桌面应用程序。
与来自 GitHub 的自定义 Electron + Vue 样板项目相比,最显着的优势是 Quasar 具有定期发布周期,并为旧版本提供升级指南。
查看我的“Scrum Daily Standup Picker” GitHub 存储库以查看更复杂的 “Quasar-Electron-Vue3-Typescript-Pinia” 项目。以下演示的演示源代码为,可在 GitHub获得。
如果您喜欢这篇文章,请在Twitter上关注我,以获取有关我的新博客文章和更多内容的通知。
或者(或另外),您也可以订阅我的时事通讯。
更多推荐




所有评论(0)