如何在插件中复用内置的管理面板组件
页面摘要: 内置的管理面板组件通过组件注册表(component registry)暴露,你可以使用
useStrapiApphook 读取该注册表。本指南以媒体库对话框(MediaLibraryDialog)为例:从注册表中获取它,然后渲染它来复用 Strapi 的资源选择对话框,也可以使用initiallySelectedAssets属性预先选中资源。
开发 Strapi 插件 或自定义管理面板时,你可能希望复用 Strapi 已经在管理面板中提供的内置 React 组件,而不是自己从零构建。内置组件通过管理面板的组件注册表暴露,你可以使用 useStrapiApp hook 来访问它。
本指南以媒体库对话框(MediaLibraryDialog)为例,但同样的方法适用于在管理面板中注册的任何组件。
从注册表访问组件
内置的管理面板组件存储在 Strapi 应用上下文(app context)的 components 对象中。使用 useStrapiApp hook 读取它,传入消费组件的名称和一个选择器(selector):
import { useStrapiApp } from '@strapi/admin/strapi-admin';
const components = useStrapiApp('MyCustomComponent', (state) => state.components);
const MediaLibraryDialog = components['media-library'];
useStrapiApp 的第一个参数是一个用于标识消费方的标签(用于错误消息);第二个参数是返回你所需的上下文部分的选择器。
复用媒体库对话框
MediaLibraryDialog 组件会打开管理面板各处使用的同一个资源选择对话框。它接受以下属性:
| Prop | Type | Description |
|---|---|---|
onSelectAssets | (selectedAssets: File[]) => void | 必填。当用户确认选择时,会随用户选中的资源一起被调用。 |
onClose | () => void | 必填。当对话框关闭时被调用。 |
initiallySelectedAssets | File[] | 可选。对话框打开时要预先选中的媒体库资源对象。 |
allowedTypes | string[] | 可选。限制可被选择的资源类型。默认为 ['files', 'images', 'videos', 'audios']。 |
multiple | boolean | 可选。允许一次选择多个资源。默认为 true。 |
NOTE
initiallySelectedAssets 期望的是完整的媒体库资源对象(其结构与 Upload API 返回的结构相同),而不仅仅是 id 和 name。
以下示例从一个自定义组件中渲染该对话框,并在打开时预先选中资源:
import { useState } from 'react';
import { useStrapiApp } from '@strapi/admin/strapi-admin';
export function MyCustomComponent() {
const [isMediaLibraryOpen, setIsMediaLibraryOpen] = useState(false);
const components = useStrapiApp('MyCustomComponent', (state) => state.components);
const MediaLibraryDialog = components['media-library'];
// Assets to pre-select when the dialog opens.
// Each entry is a full Media Library asset object, not just an id and name.
const initialAssets = [
{ id: 1, name: 'image1.jpg' /* ...other asset fields */ },
{ id: 2, name: 'image2.png' /* ...other asset fields */ },
];
const handleSelectAssets = (assets) => {
// Handle the assets the user selected
console.log('Selected assets:', assets);
setIsMediaLibraryOpen(false);
};
return (
<>
<button type="button" onClick={() => setIsMediaLibraryOpen(true)}>
Open the Media Library
</button>
{isMediaLibraryOpen && (
<MediaLibraryDialog
initiallySelectedAssets={initialAssets}
onSelectAssets={handleSelectAssets}
onClose={() => setIsMediaLibraryOpen(false)}
/>
)}
</>
);
}
预先选中资源可确保当用户从你的自定义组件打开媒体库对话框时,之前选中的条目能够显示出来。