用Vuido打造轻量级桌面应用的实战经验分享

UP主~冰可 框架 阅读 2,885
赞 99 收藏
二维码
手机扫码查看
反馈

项目初期的技术选型

说实话,最开始接到这个项目的时候我也没想到会用 Vuido。客户的需求很简单:开发一个桌面端的轻量级日志查看工具,支持 Windows 和 macOS,界面不用太 fancy,但要能实时刷新、搜索过滤、导出文本,最好还能有点自定义配置。

用Vuido打造轻量级桌面应用的实战经验分享

按理说这种需求用 Electron 就完事了,但我之前用 Electron 打包出来的应用动不动就七八十 MB,客户那边网络环境一般,部署起来太痛苦。而且这工具后期可能要集成到他们内部的运维系统里,越轻越好。

后来翻 GitHub 的时候偶然看到 Vuido,基于 Vue 和 libui-node,直接调用系统原生 UI 组件,打包出来只有几 MB,启动也快。关键是它支持 Vue 的写法,学习成本低,我就抱着试试看的心态搭了个 demo,结果发现基本功能都能实现,于是决定赌一把。

第一个版本跑起来了,但问题一堆

初始化项目用了官方推荐的模板:

npx create-vuido-app my-logger-tool

结构挺清晰,main.js 是主进程入口,App.vue 是主组件。我照着改了一版,把日志读取逻辑加上去,用 fs.watch 监听文件变化,再通过事件发给前端更新。代码大概长这样:

// main.js
const { App, Window, Box, TextArea } = require('vuido')
const fs = require('fs')

class MainWindow extends Window {
  constructor() {
    super({
      title: 'Log Viewer',
      width: 800,
      height: 600,
      margined: true
    })

    const box = new Box({
      vertical: true,
      padded: true
    })

    this.textArea = new TextArea({
      readOnly: true
    })

    box.append(this.textArea, true)

    this.setChild(box)

    this.loadLogs()
    this.watchLogFile()
  }

  loadLogs() {
    try {
      const content = fs.readFileSync('./app.log', 'utf-8')
      this.textArea.setText(content)
    } catch (err) {
      this.textArea.setText('无法读取日志文件')
    }
  }

  watchLogFile() {
    fs.watch('./app.log', () => {
      this.loadLogs()
    })
  }
}

const app = new App()

app.on('ready', () => {
  new MainWindow()
})

app.start()

Vue 部分其实没怎么动,主要是数据展示和输入框做搜索:

<!-- App.vue -->
<template>
  <Window title="Log Viewer" width="800" height="600">
    <Box vertical padded>
      <Entry v-model="search" placeholder="输入关键字搜索..." />
      <Button @click="performSearch">搜索</Button>
      <TextArea :text="filteredLogs" readonly />
    </Box>
  </Window>
</template>

<script>
export default {
  data() {
    return {
      search: '',
      rawLogs: '',
      filteredLogs: ''
    }
  },
  methods: {
    performSearch() {
      if (!this.search) {
        this.filteredLogs = this.rawLogs
      } else {
        this.filteredLogs = this.rawLogs
          .split('n')
          .filter(line => line.includes(this.search))
          .join('n')
      }
    },
    updateLogs(logs) {
      this.rawLogs = logs
      this.filteredLogs = logs
    }
  }
}
</script>

最大的坑:性能问题

一开始测试小日志文件(几十 KB)完全没问题,但换成真实环境的 log 文件——动辄几百 MB,直接卡死。textarea setText 操作一旦数据量大,UI 线程就阻塞,整个窗口无响应。我试过节流、防抖、分块读取,都没根本解决。

后来折腾了半天发现,libui 对大文本的支持本来就有缺陷,而 Vuido 又是直接封装的 libui-node,根本没法异步渲染。我甚至试过把文本拆成数组,用多个 Label 拼接显示,结果布局乱成一锅粥,还更卡。

最后只能妥协:加个最大读取限制。改成只读最后 5 万行:

function readLastNLines(filePath, n = 50000) {
  try {
    const data = fs.readFileSync(filePath, 'utf-8')
    const lines = data.split('n')
    return lines.slice(-n).join('n')
  } catch {
    return '读取失败'
  }
}

虽然不完美,但至少不会崩了。用户如果真要看全量日志,让他们用别的工具吧,这也不是这个工具的核心目标。

又踩坑了:搜索功能响应慢

接下来是搜索。原以为正则搞定就行,结果上万行文本里做 includes 匹配,输入框一打字就卡顿。开始没想到要做优化,后来加了 debounce,延迟 300ms 才触发搜索:

watch: {
  search(newVal) {
    this.debounceSearch(newVal)
  }
},
methods: {
  debounceSearch: _.debounce(function (val) {
    this.performSearch(val)
  }, 300)
}

但这里注意我踩过好几次坑:_ 是 lodash,你得先 npm install lodash。Vuido 项目默认不带这些工具库,得手动加。而且不能用 import,因为底层是 Node 环境,要用 require:

const _ = require('lodash')

最终的解决方案

综合下来,最后的方案是:

  • 限制单次加载日志不超过 5 万行
  • 使用 fs.watch 监听文件变化,自动刷新
  • 搜索使用 debounce + 字符串 filter
  • 增加“清空”“重新加载”按钮,避免缓存问题
  • 导出功能用原生 fs.writeFileSync 实现,保存为 .txt

导出那段代码其实特别简单:

exportLogs() {
  const path = require('path')
  const { saveFileDialog } = require('vuido')

  const filePath = saveFileDialog({
    title: '保存日志',
    filters: [{ name: '文本文件', pattern: '*.txt' }]
  })

  if (filePath) {
    fs.writeFileSync(filePath, this.filteredLogs, 'utf-8')
  }
}

回顾与反思

做完这个项目,我对 Vuido 的认知彻底变了。它不是用来做复杂 UI 的,而是适合那种“需要原生桌面体验 + 功能简单”的场景。如果你要做类似设置面板、日志监控、轻量工具类应用,它是真的香——打包小、启动快、API 简洁。

但它不适合做大体量数据展示,也不适合复杂交互。比如你要做富文本编辑器、表格排序筛选一大堆列,别碰它。

另外,文档是真的少,遇到问题基本靠翻 GitHub issues。社区也不活跃,很多 bug 提了没人回。但我们这个项目影响不大,关键路径都走通了。

还有一个小问题到现在没完美解决:Mac 下窗口关闭后进程偶尔不退出,得手动 kill。查了一圈怀疑是 fs.watch 没 properly close,但我加了 process.on(‘exit’) 也没完全搞定。不过实际使用中影响很小,用户基本不会频繁开关,就放着了。

总结一下

Vuido 这个技术,属于“冷门但能救命”的类型。Electron 太重的时候,你可以想想有没有更轻的方案。Vuido 就是其中一个选择,前提是你接受它的局限性。

以上是我个人对这个项目的完整分享,有更优的实现方式或者更好的桌面轻量化方案,欢迎评论区交流。这个技巧的拓展用法还有很多,后续我也会继续分享这类实战经验。

以上是我踩坑后的总结,希望对你有帮助。

本文章不代表JZTHEME立场,仅为作者个人观点 / 研究心得 / 经验分享,旨在交流探讨,供读者参考。
发表评论
Top丶佼佼
大家有没有对应的实操工具可以推荐?
点赞
2026-03-20 22:25