Electron和Vite结合的一些思考

本文介绍了如何在Electron项目中集成Vite,包括创建Vite工程、配置Electron启动入口,以及处理开发环境和生产环境的差异。同时提到了Vite中使用Node.js的局限性。作者最后推荐了另一种更完整的开发方式,即分离Electron组件和Vue库的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景

Electron和Vite都有各自的应用场景。单独运行Electron或者Vite工程是非常容易的,官方文档有详细的教程。但是把两者结合起来有一些要注意的地方。本文通过搭建一个Electron + Vite的示例应用来说明两者结合的方式及存在的问题。

1、启动Vite

用Vite脚手架创建一个工程,指定工程名称,其余保持默认即可。

npm create vue@latest

 命令行安装Vite

进入工程文件夹,安装依赖

npm install

执行启动命令

npm run dev

 命令行启动Vite

通过链接可访问Vite工程,可以看到这是一个传统的Web前端页面。

 Vite启动页面 

2、启动Electron

npm install --save-dev electron

 这里electron作为开发依赖就可以,为什么生产环境不需要,官方给出了解释

要运行electron工程,必须在package.json中指定入口点文件(main),此外为了方便增加一条启动electron工程的命令 

Electron配置

此时已存在src/main.js,但这是Vite的main.js 

Vite的main.js 

在根目录下创建electron的main.js

    const { app, BrowserWindow } = require('electron')

    const createWindow = () => {
      const win = new BrowserWindow({
        width: 800,
        height: 600
      })

      win.loadFile('index-electron.html')
    }

    app.whenReady().then(() => {
      createWindow()
    })

Electron的main.js 

 创建electron窗口加载的网页,由于vite已经有了一个index.html,electron的html我们叫它index-electron.html

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="UTF-8" />
        <!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
        <meta
          http-equiv="Content-Security-Policy"
          content="default-src 'self'; script-src 'self'"
        />
        <meta
          http-equiv="X-Content-Security-Policy"
          content="default-src 'self'; script-src 'self'"
        />
        <title>Hello from Electron renderer!</title>
      </head>
      <body>
        <h1>Hello from Electron renderer!</h1>
        <p>👋</p>
      </body>
    </html>

Electron加载的html页面 

 执行以下命令启动Electron桌面端应用程序

npm run start:electron

 Electron桌面应用

3、Electron + Vite

Vite启动拿到的是一个url,正好electron有加载URL地址的api。这样Electron就可以通过Vite工程的地址将Vite包含进来。

Electron加载URL的API 

对main.js做如下修改

Electron加载Vite发布的URL

启动两个命令行窗口,一个启动vite,另一个启动electron,可以看到electron成功加载了vite的网页


Vite加载到Electron的效果

 启动两个命令行窗口毕竟麻烦,这里可以安装npm-run-all三方库来并行执行

npm install npm-run-all --save-dev

在package.json里加入并行执行的命令,需要时执行即可

"dev:all": "npm-run-all -p dev start:electron"

并行启动Electron和Vite 

开发环境下可以这么用,生产环境下需要调整。在执行npm run build之后会生成一个dist文件夹,生产环境下调用该文件夹的网页内容

npm run build

 生产环境Vite的dist文件夹

因此,为了兼顾生产环境需要在main.js中做如下修改

Electron中区分开发环境和生产环境

main.js最终代码文本如下

    const { app, BrowserWindow } = require('electron')

    const isDev = app.isPackaged !== 'true';

    const createWindow = () => {
      const win = new BrowserWindow({
        width: 800,
        height: 600
      })

      // win.loadURL('http://localhost:5173/')

      if (isDev) {
        win.loadURL('http://localhost:5173/');
      } else {
        win.loadFile(path.join(__dirname, 'dist', 'index.html'));
      }
    }

    app.whenReady().then(() => {
      createWindow()
    })

Electron的main.js文件 

 执行npm run dev:all可以看到结合的效果

npm run dev:all

Electron结合Vite

4、Vite中使用Node.js(不推荐) 

Electron桌面应用往往需要调用Node.js的API,而我们这种方案其实只是把Electron当一个“壳”,内容全靠Vite提供。那么要调用Node.js的API只能在Vite(网页)中完成。

通过rollup-plugin-node-polyfills插件可以让浏览器支持部分Node.js API,但支持的很不全,基本上没有实用价值。

结语

经过一段时间的实践,发现Electron结合Vite的方案实用性有所不足,不能很方便的操作Node.js和Electron提供的本地桌面应用开发能力。(花时间走通的方案又被自己否定了,有点小小的可惜)

后来我在实际应用中没有用Vite脚手架,而是引入Vue的预编译包,把Vue当作一个界面库来用。Electron部分把主进程(main)、渲染器进程(renderer)、预加载脚本(preload)、网页(html)、样式(css)、静态库(public)等几个部分分离开来。组织结构如下图所示。

实际开发中的组织结构 

如果只是想给网页套个桌面的壳子,可以使用本文介绍的这种Electron + Vite的方案;如果想深入的开发本地桌面应用程序,还是自己组织模块然后用webpack + Electron Forge打包为好。

<think>好的,我现在需要帮助用户解决如何在Electron、Vue3TypeScript中实现动态搜索页面的问题。用户的需求是初始状态下只有一个居中的搜索框,输入文字并点击按钮后,搜索框上移,下方显示结果列表,并且要有动态效果。我需要逐步思考如何实现这个功能。 首先,我应该考虑项目的搭建。用户使用的是Electron,所以可能需要使用electron-vite或者Vue CLI来初始化项目。确保Vue3TypeScript的配置正确。然后,安装必要的依赖,比如vue-router、pinia(如果需要状态管理)等。不过根据问题描述,可能暂时不需要路由,但先记下来。 接下来是页面结构的构建。用户需要一个初始居中的搜索框,这可以通过CSS的flex布局实现。将搜索框包裹在一个容器中,设置容器为flex,justify-contentalign-items都为center,这样搜索框就会水平垂直居中。然后,当输入文字并点击按钮后,搜索框需要上移,下方显示列表。这时候可能需要改变容器的样式,比如通过动态类名或者内联样式调整位置。同时,下方的列表需要动态显示,可能使用v-if或者v-show指令来控制可见性。 动态效果方面,Vue的过渡组件<transition>可以用来实现平滑的动画效果。当搜索框上移时,可以应用CSS过渡属性,比如transition: all 0.3s ease,这样位置变化会有动画。同时,列表的显示隐藏也可以使用<transition-group>来实现渐显或滑入的效果。 关于输入按钮的事件处理,需要在Vue组件中定义数据属性,比如searchText来绑定输入框的值,isSearching来控制搜索框的状态。当用户点击按钮或按下回车时,触发搜索方法,将isSearching设为true,触发样式变化列表显示。 在Electron方面,可能需要处理窗口的大小变化。当搜索框上移后,窗口的高度可能需要调整,或者内容区域需要滚动。这里可能需要调用Electron的API来调整窗口尺寸,比如使用mainWindow.setSize(width, height)。但需要确保在渲染进程中通过IPC与主进程通信来实现。 代码结构方面,组件模板部分需要包含输入框、按钮结果列表。使用Vue的响应式数据绑定,将输入框的v-model绑定到searchText,按钮的@click事件绑定到handleSearch方法。结果列表使用v-for指令遍历搜索结果,并应用过渡效果。 样式部分需要注意定位的变化。初始时,搜索框的容器可能是position: absolute或fixed,top: 50%来居中。点击后,改为top: 20px这样的固定位置,并调整容器的高度,让列表有空间显示。同时,列表可能需要max-heightoverflow-y: auto来支持滚动。 测试时需要考虑不同情况,比如输入为空时的处理,搜索结果的加载状态,以及Electron窗口的响应式行为。可能需要添加错误处理加载提示。 最后,需要整合所有部分,确保TypeScript类型正确,没有编译错误,并且Electron应用能正确打包运行。可能还需要优化性能,比如防抖输入处理,避免频繁搜索。 总结步骤: 1. 创建项目并安装依赖。 2. 构建页面结构样式,实现居中布局。 3. 添加响应式数据事件处理。 4. 实现动态样式变化过渡动画。 5. 处理Electron窗口调整。 6. 测试优化。</think>我将分步骤为您说明如何实现这个动态搜索界面,结合技术实现要点代码示例。 ### 一、环境搭建 1. 使用`electron-vite`初始化项目 ```bash npm create electron-vite@latest my-app --template vue-ts ``` 2. 安装必要依赖 ```bash cd my-app && npm install ``` ### 二、核心组件实现(App.vue) ```typescript <script setup lang="ts"> import { ref } from 'vue' const searchText = ref('') const isSearching = ref(false) const results = ref<string[]>([]) const handleSearch = () => { if (!searchText.value) return isSearching.value = true // 模拟搜索请求 setTimeout(() => { results.value = Array.from({length: 10}, (_,i) => `结果 ${i+1}: ${searchText.value}`) }, 500) } </script> <template> <div class="container" :class="{ 'search-active': isSearching }"> <div class="search-box"> <input v-model="searchText" type="text" placeholder="输入搜索内容" @keyup.enter="handleSearch" > <button @click="handleSearch"> 🔍 </button> </div> <transition name="list"> <ul v-if="isSearching" class="result-list"> <li v-for="(item, index) in results" :key="index"> {{ item }} </li> </ul> </transition> </div> </template> ``` ### 三、动态样式实现(style.css) ```css .container { height: 100vh; display: flex; flex-direction: column; align-items: center; transition: all 0.5s cubic-bezier(0.4, 0, 0.2, 1); } /* 初始居中状态 */ .container:not(.search-active) { justify-content: center; } /* 激活搜索状态 */ .search-active { padding-top: 50px; } .search-box { display: flex; gap: 10px; transition: transform 0.3s ease; } input { width: 300px; padding: 12px 20px; border: 2px solid #42b883; border-radius: 25px; font-size: 16px; } button { padding: 12px 25px; background: #42b883; border: none; border-radius: 25px; color: white; cursor: pointer; } .result-list { width: 500px; max-height: 60vh; overflow-y: auto; margin-top: 30px; padding: 0; list-style: none; } /* 过渡动画 */ .list-enter-active, .list-leave-active { transition: all 0.5s ease; } .list-enter-from, .list-leave-to { opacity: 0; transform: translateY(-20px); } ``` ### 四、窗口控制逻辑(main.ts) ```typescript import { app, BrowserWindow, ipcMain } from 'electron' let mainWindow: BrowserWindow function createWindow() { mainWindow = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true, contextIsolation: false } }) // 监听搜索状态变化 ipcMain.on('search-state-changed', (_, isSearching) => { if (isSearching) { mainWindow.setSize(800, 800) // 扩展窗口高度 } else { mainWindow.setSize(800, 600) } }) } ``` ### 五、实现原理说明 1. **布局控制**:通过CSS的`flex`布局实现初始居中,使用`transform``transition`实现平滑移动动画 2. **响应式设计**:利用Vue的响应式系统(`ref`)管理搜索状态 3. **窗口控制**:通过Electron的IPC通信实现窗口尺寸动态调整[^1] 4. **性能优化**:使用CSS硬件加速(`transform`属性)确保动画流畅[^2]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值