Halo 插件如何为 Console 数据列表添加自定义操作菜单项(list-item:operation:create)
2026/9/10 5:44:46 网站建设 项目流程

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-kitvite@vitejs/plugin-vuevite.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-clientaxios都可直接从 Halo 共享运行时导入(ESM 输出下由 Import Map 提供,无需自行打包);vuemarkRaw同理。

支持扩展的数据列表

目前支持扩展的数据列表及对应扩展点名称如下(引自 扩展点文档):

数据列表扩展点名称
文章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>[]>(各列表替换为对应类型,如ListedCommentPluginThemeBackupAttachment)。回调接收一个 VueRef包裹的行数据,可以同步返回菜单项数组,也可以返回 Promise。

在 UI 插件入口注册扩展点

在 UI 项目的入口文件(src/index.ts)中,用@halo-dev/ui-shareddefinePlugin导出插件模块,并在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/componentsVDropdownItem,也可以传自定义组件,组件的 props 通过props字段传入。
  • action是点击事件回调,参数为当前行的数据(示例中为ListedPost);回调内示例请求了/apis/api.console.halo.run/v1alpha1/posts/{文章名}/head-content接口取回正文,再在前端构造 Blob 触发下载,文件名取post.spec.title并拼接.md后缀。
  • hiddentrue时该项隐藏;permissions用于声明权限,children可挂子菜单。
  • 回调也可以接收行参数(如(post: Ref<ListedPost>) => ...),在返回菜单项时按行数据动态决定hiddenlabel等字段;不关心行数据时直接返回固定数组(如示例)也可以。

如果你需要的是扩展列表的“显示字段”而不是操作菜单,对应的是另一个扩展点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 中打开文档说明的对应列表页面(文章、评论、回复、插件、备份、主题、附件):

  1. 操作菜单可见性:找到任意一行的操作下拉菜单,其中应出现你注册的菜单项(示例中为“导出为 Markdown 文档”),位置由priority决定;未出现时,先确认扩展点名称与列表匹配(如文章列表只能用post:list-item:operation:create),以及插件的 UI 资源是否随插件正常加载。
  2. 点击行为:点击该菜单项后,示例代码会发起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),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询