Electron+Vite项目实战:从零封装一个带Pinia状态管理的跨平台Markdown编辑器

张开发
2026/4/5 13:52:42 15 分钟阅读

分享文章

Electron+Vite项目实战:从零封装一个带Pinia状态管理的跨平台Markdown编辑器
ElectronVite项目实战从零封装一个带Pinia状态管理的跨平台Markdown编辑器在当今快节奏的开发环境中能够快速构建高性能、跨平台的桌面应用已经成为前端开发者的核心竞争力之一。Electron作为最流行的跨平台桌面应用框架结合Vite这一新一代前端构建工具为开发者提供了前所未有的开发体验。本文将带你从零开始构建一个功能完整的Markdown编辑器集成Vue3、TypeScript和Pinia等现代前端技术栈打造一个既美观又实用的开发工具。1. 环境准备与项目初始化构建一个Electron应用的第一步是搭建开发环境。与传统Electron项目不同我们将使用electron-vite这一专为Electron优化的构建工具它能显著提升开发效率。首先确保你的系统满足以下要求Node.js 18.x或更高版本npm 8.x或yarn 1.22.x或pnpm 6.xGit可选用于版本控制创建新项目最简单的方式是使用官方脚手架pnpm create quick-start/electron my-markdown-editor --template vue-ts这个命令会创建一个基于Vue3和TypeScript的Electron项目骨架。创建过程中脚手架会询问几个配置选项是否添加Electron更新插件推荐选择Yes是否启用Electron下载镜像代理国内用户建议选择Yes项目创建完成后目录结构大致如下my-markdown-editor/ ├── src/ │ ├── main/ # 主进程代码 │ ├── preload/ # 预加载脚本 │ └── renderer/ # 渲染进程代码Vue应用 ├── electron.vite.config.js # 统一配置文件 └── package.json2. 核心功能开发Markdown编辑器实现2.1 编辑器界面搭建我们将使用Vue3的组合式API来构建编辑器界面。首先安装必要的依赖pnpm add vueuse/core marked highlight.js然后创建一个基础的编辑器组件!-- src/renderer/components/Editor.vue -- script setup langts import { ref, watch } from vue import { marked } from marked import hljs from highlight.js import highlight.js/styles/github.css const content ref(# Hello Markdown!) const htmlContent ref() marked.setOptions({ highlight: (code, lang) { return hljs.highlightAuto(code, [lang]).value } }) watch(content, (newVal) { htmlContent.value marked(newVal) }, { immediate: true }) /script template div classeditor-container textarea v-modelcontent classeditor-input/textarea div classpreview v-htmlhtmlContent /div /div /template style scoped .editor-container { display: grid; grid-template-columns: 1fr 1fr; height: 100vh; } .editor-input { padding: 1rem; border: none; resize: none; font-family: monospace; } .preview { padding: 1rem; overflow: auto; } /style2.2 文件操作功能集成Electron的强大之处在于可以直接访问文件系统。我们需要在主进程和渲染进程之间建立安全的通信通道。首先在预加载脚本中暴露API// src/preload/index.ts import { contextBridge, ipcRenderer } from electron contextBridge.exposeInMainWorld(electronAPI, { openFile: () ipcRenderer.invoke(dialog:openFile), saveFile: (content: string) ipcRenderer.invoke(file:save, content) })然后在主进程中实现对应的处理逻辑// src/main/index.ts import { ipcMain, dialog } from electron import { readFile, writeFile } from node:fs/promises ipcMain.handle(dialog:openFile, async () { const { canceled, filePaths } await dialog.showOpenDialog({ properties: [openFile], filters: [{ name: Markdown, extensions: [md, markdown] }] }) if (!canceled) { return await readFile(filePaths[0], utf-8) } }) ipcMain.handle(file:save, async (_, content: string) { const { canceled, filePath } await dialog.showSaveDialog({ filters: [{ name: Markdown, extensions: [md] }] }) if (!canceled filePath) { await writeFile(filePath, content) } })3. 状态管理Pinia集成与主题切换3.1 Pinia基础配置Pinia是Vue3推荐的状态管理库比Vuex更简单、更符合组合式API的思维模式。首先安装Piniapnpm add pinia pinia/nuxt创建store配置文件// src/renderer/stores/index.ts import { createPinia } from pinia export const pinia createPinia()在Vue应用中启用Pinia// src/renderer/main.ts import { createApp } from vue import App from ./App.vue import { pinia } from ./stores const app createApp(App) app.use(pinia) app.mount(#app)3.2 主题状态管理创建一个管理主题的store// src/renderer/stores/theme.ts import { defineStore } from pinia import { ref, watch } from vue type Theme light | dark export const useThemeStore defineStore(theme, () { const theme refTheme( localStorage.getItem(theme) as Theme || light ) watch(theme, (newTheme) { document.documentElement.setAttribute(data-theme, newTheme) localStorage.setItem(theme, newTheme) }, { immediate: true }) function toggle() { theme.value theme.value light ? dark : light } return { theme, toggle } })在组件中使用主题store!-- src/renderer/components/ThemeToggle.vue -- script setup langts import { useThemeStore } from ../stores/theme const theme useThemeStore() /script template button clicktheme.toggle {{ theme.theme light ? : ☀️ }} /button /template4. 高级功能与优化4.1 自定义标题栏Electron默认的标题栏在不同平台上样式不一致我们可以创建一个自定义标题栏!-- src/renderer/components/TitleBar.vue -- script setup langts import { onMounted } from vue import { ipcRenderer } from electron function minimize() { ipcRenderer.send(window:minimize) } function maximize() { ipcRenderer.send(window:maximize) } function close() { ipcRenderer.send(window:close) } /script template div classtitle-bar div classtitleMarkdown Editor/div div classcontrols button clickminimize−/button button clickmaximize□/button button clickclose×/button /div /div /template style scoped .title-bar { -webkit-app-region: drag; display: flex; justify-content: space-between; align-items: center; padding: 0 1rem; height: 30px; background-color: var(--titlebar-bg); } .controls { -webkit-app-region: no-drag; display: flex; } .controls button { padding: 0 1rem; background: none; border: none; font-size: 1rem; } /style对应的主进程处理// src/main/index.ts ipcMain.on(window:minimize, () { mainWindow.minimize() }) ipcMain.on(window:maximize, () { if (mainWindow.isMaximized()) { mainWindow.unmaximize() } else { mainWindow.maximize() } }) ipcMain.on(window:close, () { mainWindow.close() })4.2 打包与分发使用electron-builder可以方便地打包应用pnpm add electron-builder -D在package.json中添加打包脚本{ scripts: { build: electron-vite build electron-builder }, build: { appId: com.example.markdowneditor, productName: Markdown Editor, directories: { output: dist }, files: [out/**/*], mac: { category: public.app-category.developer-tools }, win: { target: nsis }, linux: { target: AppImage } } }运行打包命令pnpm build打包完成后你会在dist目录下找到对应平台的安装包。5. 性能优化与调试技巧5.1 开发环境优化electron-vite已经为我们提供了优秀的开发体验但我们还可以进一步优化// electron.vite.config.js export default { renderer: { server: { open: false // 禁止自动打开浏览器 } }, main: { plugins: [ { name: watch-external, configureServer(server) { server.watcher.add(src/main/**/*.ts) } } ] } }5.2 生产环境优化为了减小应用体积我们可以配置external选项// electron.vite.config.js export default { main: { build: { rollupOptions: { external: [electron, fs, path] } } } }5.3 调试技巧Electron应用的调试可以分为两部分渲染进程和普通网页一样可以使用Chrome开发者工具主进程需要附加调试器在启动脚本中添加调试参数{ scripts: { debug: electron-vite dev --inspect9229 } }然后在VSCode中创建调试配置{ version: 0.2.0, configurations: [ { name: Debug Main Process, type: node, request: attach, port: 9229, protocol: inspector } ] }6. 扩展功能思路虽然我们已经实现了一个基本的Markdown编辑器但还有很多可以扩展的方向实时预览同步滚动实现编辑器和预览面板的同步滚动导出功能支持导出为PDF、HTML等格式插件系统允许用户通过插件扩展编辑器功能云同步集成云存储服务实现多设备同步快捷键自定义允许用户自定义快捷键代码片段支持快速插入常用代码片段实现这些功能需要深入Electron和前端技术的各个方面但正是这些扩展性使得Electron应用如此强大。

更多文章