30分钟开发你自己的Hestia小组件:BaseApp与Registry机制完全教程 【免费下载链接】hestia-coreA grid-based, modular dashboard built entirely from HTML, CSS, and JS with the ability to create your custom API integrations.项目地址https://gitcode.com/gh_mirrors/he/hestia-core点击查看免费下载Hestia 是一个纯 HTML、CSS、JavaScript 构建的网格化仪表盘Dashboard内置时钟、天气、Glances 监控等组件也支持接入 Pi-hole、Jellyfin 等家庭服务 API。它最吸引人的设计是任何人都能用自己的 API 集成能力扩展它——因为一个自定义小组件Widget只需继承BaseApp类、调用一次registry.register注册即可上线全程无需构建工具也没有后端依赖。一、为什么 30 分钟就够先看懂这套组件机制Hestia 的组件开发只有三步闭环写类继承 baseApp.js 导出的BaseApp实现render方法返回 HTML 字符串注册调用 registry.js 单例的register(type, AppClass, metadata)登记组件类型、默认尺寸和设置表单导入在 appIndex.js 中加一行import组件就会出现在仪表盘的Add New App列表里。整个流程不涉及打包、不涉及路由所有逻辑都是原生 ES Module。下面拆开这两个核心文件。二、两大核心BaseApp 与 Registry2.1 BaseApp每个组件必须遵守的最小契约打开 js/apps/baseApp.js你会发现它只有 10 行代码export class BaseApp { constructor() { // Shared logic can go here later } // All apps must implement this async render(appData) { throw new Error(Render method not implemented); } }它定义了组件生命周期的两个方法方法是否必须作用async render(app)✅ 必须实现返回组件卡片的 HTML 字符串app对象包含该组件的位置、尺寸和用户保存的设置app.dataonMount(el, app)⭕ 可选HTML 插入 DOM 后执行适合绑定事件、启动定时器、请求 API这种先渲染静态 HTML再挂载动态逻辑的分离设计是 Hestia 组件模型的关键render负责长什么样onMount负责做什么。2.2 Registry带样式自动注入的组件注册表registry.js 导出了一个全局单例registry核心是register方法registry.register(my-app, MyApp, { label: My Cool App, // Add App 列表里显示的名称 category: static, // 可选分类 defaultSize: { cols: 2, rows: 1 }, // 网格默认占用尺寸 settings: [ /* 设置项数组 */ ], css: .my-app { ... } // 组件专属样式注册时自动注入 style });register做了两件关键的事见 registry.js#L8-L21把Class和metadata存入this.apps[type]。注意如果 type 已存在会直接忽略不会覆盖这是防止命名冲突的保护如果元数据里带了css立即通过injectStyles注入到页面head且每个组件只注入一次。注册完成后网格系统和编辑面板都从注册表取数grid.js 中的mountAppContent会用registry.get(app.subtype)找到组件类实例化后依次调用render→ 插入 DOM →onMountappEditor.js 用registry.getAll()渲染Add New App弹窗并根据settings数组自动生成设置表单——你不用手写任何表单 DOM。三、四步开发你的第一个组件以官方示例 helloWorld.js 为蓝本完整流程如下。先获取源码git clone https://gitcode.com/gh_mirrors/he/hestia-core第 1 步创建文件js/apps/myApp.js第 2 步继承 BaseApp 实现 renderimport { BaseApp } from ./baseApp.js; import { registry } from ../registry.js; class MyHello extends BaseApp { async render(app) { const text app.data.text || Hello, Hestia!; return div classapp-content app-type-myhello h2${text}/h2 /div; } }app.data里保存着用户在设置面板填写的所有值以及卡片背景色、文字色记得对每个字段提供默认值兜底。第 3 步注册组件registry.register(my-hello, MyHello, { label: My Hello, category: static, defaultSize: { cols: 2, rows: 1 }, settings: [ { name: text, label: Greeting Message, type: text, placeholder: e.g. Hello, World! } ], css: .app-type-myhello { display: flex; align-items: center; justify-content: center; height: 100%; color: inherit; } });settings数组支持的type包括text、select需配options、textarea、image-source图片链接或上传自动存入 IndexedDB。每个字段的name就是app.data里的键名label会原样显示在设置表单中。第 4 步在 appIndex.js 中导入在 js/apps/appIndex.js 末尾加一行import ./myApp.js;刷新页面点击工具栏的Add New App你的组件就出现在列表里了。添加后卡片会自动寻找空闲网格位置findEmptySlot逻辑在 grid.js双击标题还能重命名。上图正是默认仪表盘里 Image Frame 组件加载 constants.js 中预设素材的渲染效果——它本身就是一个注册在注册表里的组件。四、进阶让组件动起来静态文本只是起点。参考 clockApp.js在onMount里可以操作 DOM、启动定时器onMount(el, app) { const timeEl el.querySelector(.clock-time); const update () { // 安全检查卡片被删除后停止运行避免内存泄漏 if (!el.isConnected) { clearInterval(intervalId); return; } timeEl.innerText new Date().toLocaleTimeString(); }; update(); const intervalId setInterval(update, 1000); }两个值得学习的关键点el.isConnected检查用户删除卡片时 DOM 节点会被移除定时器必须随之停止否则会出现幽灵更新el是整张卡片的元素用el.querySelector查找内部节点。如果要接 API轮询数据、绘制图表官方 Glances 组件是最好的模板glancesApp.js 展示了setInterval轮询 错误兜底404/离线提示 按指标切换子模块逻辑拆在 js/apps/glances/ 目录下的完整写法。五、常见坑点清单坑现象解法忘记在 appIndex.js 导入组件不显示在 Add App 列表加import ./myApp.js;该文件被 main.js 间接加载type 命名冲突注册被静默忽略打开控制台看[Registry] Registered:日志确认忘记写默认值新卡片显示undefinedapp.data.xxx一律用|| 默认值兜底onMount 里泄漏定时器删除卡片后 CPU 持续占用每次 tick 前检查el.isConnected样式污染其他组件全局 class 名撞车用.app-type-xxx作用域前缀CSS 已按组件隔离注入六、关键文件速查文件职责js/apps/baseApp.js组件基类定义 render 契约js/registry.js注册表单例与样式注入js/apps/appIndex.js组件导入总入口js/apps/helloWorld.js最简完整示例推荐先读js/apps/clockApp.jsonMount 定时器示例js/apps/glancesApp.jsAPI 轮询 图表 错误处理模板js/grid.js网格渲染、组件挂载、空闲位置查找js/ui/appEditor.jsAdd/Edit App 弹窗与设置表单生成index.html页面骨架与工具栏按钮从render返回一段 HTML到registry.register登记一个类型Hestia 的 BaseApp Registry 机制把组件开发压缩成了三件事。照着 helloWorld.js 抄一遍、换上自己的数据源你的第一个自定义小组件 30 分钟就能上线。赞分享【免费下载链接】hestia-coreA grid-based, modular dashboard built entirely from HTML, CSS, and JS with the ability to create your custom API integrations.项目地址https://gitcode.com/gh_mirrors/he/hestia-core点击查看免费下载相关推荐用shadcn registry机制搭建你自己的组件注册表以brainless为例的完整开发者教程用shadcn registry机制搭建你自己的组件注册表以brainless为例的完整开发者教程 brainless 是一个把 Claude Code、Co10 分钟开发你自己的回复 ProviderSightFlow Provider Hub 插件系统完整教程manifest.json bundle10 分钟开发你自己的回复 ProviderSightFlow Provider Hub 插件系统完整教程manifest.json bundle SZCode 插件开发完全指南10分钟打造你自己的 Skills、命令与 MCP 插件ZCode 插件开发完全指南10分钟打造你自己的 Skills、命令与 MCP 插件 ZCode 插件开发 是让 Z.ai 智能编程助手coding age上一篇Flink 调试窗口与事件时间监控 currentInputWatermark 指标与处理迟到的散乱事件下一篇SpaceX-API v5 单次发射查询指南深入解析 GET /v5/launches/:id 端点创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考