Halo 插件如何为 Console 数据列表添加自定义操作菜单项(list-item:operation:create)
【免费下载链接】haloHalo 是一款强大易用的开源建站工具,从个人博客、知识库,到企业官网、在线商城,Halo 都能助您轻松实现,一站式满足您的多样化建站需求。项目地址: https://gitcode.com/GitHub_Trending/ha/halo
Halo 2 的 Console 中,数据列表统一由 Entity 组件渲染,Entity 组件内为每行数据预留了操作按钮插槽。当你开发插件时,希望给文章、评论、插件等列表的行操作菜单追加一个自己的入口(例如“导出为 Markdown 文档”),就可以使用list-item:operation:create系列的 Entity 数据列表操作菜单扩展点。完成本文后,你会在自己的插件中注册该扩展点,使新的菜单项出现在对应数据列表的操作下拉菜单里,并响应点击事件。
前提条件
- 你已有一个 Halo 插件工程,其中包含 UI 插件前端项目(源码入口默认约定为
src/index.ts,如ui-plugin/目录结构所示)。 - UI 项目已按 Halo UI 插件构建工具包 配置了构建:以 Vite 为例,安装
@halo-dev/ui-plugin-bundler-kit、vite与@vitejs/plugin-vue,vite.config.ts从@halo-dev/ui-plugin-bundler-kit/vite导入viteConfig(自 2.26.0 起包根导入已弃用)。Node.js 要求为^18.0.0 || >=20.0.0。 - 扩展点代码中用到的
@halo-dev/ui-shared、@halo-dev/components、@halo-dev/api-client与axios都可直接从 Halo 共享运行时导入(ESM 输出下由 Import Map 提供,无需自行打包);vue的markRaw同理。
支持扩展的数据列表
目前支持扩展的数据列表及对应扩展点名称如下(引自 扩展点文档):
| 数据列表 | 扩展点名称 |
|---|---|
| 文章 | post:list-item:operation:create |
| 评论 | comment:list-item:operation:create |
| 回复 | reply:list-item:operation:create |
| 插件 | plugin:list-item:operation:create |
| 备份 | backup:list-item:operation:create |
| 主题 | theme:list-item:operation:create |
| 附件 | attachment:list-item:operation:create |
每个扩展点的回调签名为(item: Ref<ListedPost>) => OperationItem<T>[] | Promise<OperationItem<T>[]>(各列表替换为对应类型,如ListedComment、Plugin、Theme、Backup、Attachment)。回调接收一个 VueRef包裹的行数据,可以同步返回菜单项数组,也可以返回 Promise。
在 UI 插件入口注册扩展点
在 UI 项目的入口文件(src/index.ts)中,用@halo-dev/ui-shared的definePlugin导出插件模块,并在extensionPoints中声明扩展点。下面直接采用文档示例:在文章列表中添加一个“导出为 Markdown 文档”的操作菜单项:
import type { ListedPost } from "@halo-dev/api-client"; import { VDropdownItem } from "@halo-dev/components"; import { definePlugin } from "@halo-dev/ui-shared"; import axios from "axios"; import { markRaw } from "vue"; export default definePlugin({ extensionPoints: { "post:list-item:operation:create": () => { return [ { priority: 21, component: markRaw(VDropdownItem), label: "导出为 Markdown 文档", permissions: [], action: async (post: ListedPost) => { const { data } = await axios.get( `/apis/api.console.halo.run/v1alpha1/posts/${post.post.metadata.name}/head-content` ); const blob = new Blob([data.raw], { type: "text/plain;charset=utf-8", }); const url = window.URL.createObjectURL(blob); const link = document.createElement("a"); link.href = url; link.download = `${post.post.spec.title}.md`; link.click(); }, }, ]; }, }, });示例中各字段的用途,对照OperationItem类型定义(见 扩展点文档):
export interface OperationItem<T> { priority: number; // 优先级,越小越靠前 component: Raw<Component>; // 菜单项组件,可以使用 `@halo-dev/components` 中提供的 `VDropdownItem`,也可以自定义 props?: Record<string, unknown>; // 组件的 props action?: (item?: T) => void; // 点击事件 label?: string; // 菜单项名称 hidden?: boolean; // 是否隐藏 permissions?: string[]; // 权限 children?: OperationItem<T>[]; // 子菜单 }几点与类型定义对应的说明:
priority控制菜单项排序,值越小越靠前;示例使用21。component是菜单项组件,用markRaw包裹原始组件;示例使用@halo-dev/components的VDropdownItem,也可以传自定义组件,组件的 props 通过props字段传入。action是点击事件回调,参数为当前行的数据(示例中为ListedPost);回调内示例请求了/apis/api.console.halo.run/v1alpha1/posts/{文章名}/head-content接口取回正文,再在前端构造 Blob 触发下载,文件名取post.spec.title并拼接.md后缀。hidden为true时该项隐藏;permissions用于声明权限,children可挂子菜单。- 回调也可以接收行参数(如
(post: Ref<ListedPost>) => ...),在返回菜单项时按行数据动态决定hidden、label等字段;不关心行数据时直接返回固定数组(如示例)也可以。
如果你需要的是扩展列表的“显示字段”而不是操作菜单,对应的是另一个扩展点list-item:field:create,参见 Entity 数据列表显示字段扩展点。
构建 UI 插件
扩展点代码写完后,按 构建工具包文档 的约定构建。推荐脚本(写入 UI 项目package.json):
{ "scripts": { "dev": "vite dev --mode=development --watch", "build": "vite build" } }构建产物的输出位置:
- 开发模式:输出到插件工程的
../build/resources/main/ui或../build/resources/main/console; - 生产模式:输出到
./build/dist(遗留的HaloUIPluginBundlerKit兼容输出目录为src/main/resources/console)。
生产构建的完整输出目录需要原样保留:ESM 输出额外包含保留文件名ui-plugin.json清单,可能还有内容哈希命名的chunks/与assets/,该文件由构建工具生成,不要自行创建同名文件。开发调试时运行dev脚本即可通过--watch持续观察产物更新。
验证结果
安装/更新插件后,在 Console 中打开文档说明的对应列表页面(文章、评论、回复、插件、备份、主题、附件):
- 操作菜单可见性:找到任意一行的操作下拉菜单,其中应出现你注册的菜单项(示例中为“导出为 Markdown 文档”),位置由
priority决定;未出现时,先确认扩展点名称与列表匹配(如文章列表只能用post:list-item:operation:create),以及插件的 UI 资源是否随插件正常加载。 - 点击行为:点击该菜单项后,示例代码会发起
head-content请求并触发浏览器下载一个以文章标题命名的.md文件;收到该文件即说明action回调链路(点击 → 接口请求 → 前端下载)已经跑通。
限制说明
- 目前只有上表列出的 7 种数据列表支持该扩展点,其他列表没有对应的
list-item:operation:create扩展点名称。 - 扩展点仅覆盖行操作菜单项这一插槽;若要同时扩展行上的显示字段,需要另外注册
list-item:field:create扩展点(见 显示字段扩展点文档),两者互相独立。 OperationItem中的permissions是 UI 权限标识数组;路由文档中对同类permissions的说明是:当前用户没有对应权限时不会注册对应内容(见 路由生成文档 权限一节)。
【免费下载链接】haloHalo 是一款强大易用的开源建站工具,从个人博客、知识库,到企业官网、在线商城,Halo 都能助您轻松实现,一站式满足您的多样化建站需求。项目地址: https://gitcode.com/GitHub_Trending/ha/halo
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考