Skip to main content

v4 插件迁移:迁移前端

¥v4 plugin migration: Migrating the front end

本指南是 v4 插件迁移指南 的一部分,旨在帮助你将插件从 Strapi v3.6.x 迁移到 v4.0.x。

¥This guide is part of the v4 plugin migration guide designed to help you migrate a plugin from Strapi v3.6.x to v4.0.x.

将插件的前端迁移到 Strapi v4 可能需要:

¥Migrating the front end of a plugin to Strapi v4 might require:

将插件前端迁移到 Strapi v4 应完全手动完成。

¥Migrating the front end of a plugin to Strapi v4 should be done entirely manually.

🤓 使用新的管理面板 API 进一步发展

遵循本指南应该可以帮助你使用单个视图迁移基本插件。然而,Strapi v4 中引入的 管理面板 API 允许进一步定制。

¥Following this guide should help you migrate a basic plugin with a single view. However, the Admin Panel APIs introduced in Strapi v4 allow for further customization.

除了 register() 生命周期函数 在插件加载后立即执行之外,bootstrap() 生命周期函数 在所有插件加载后执行。

¥In addition to the register() lifecycle function, which is executed as soon as the plugin is loaded, a bootstrap() lifecycle function executes after all plugins are loaded.

要添加设置链接或部分,使用 Redux reducer,钩子其他插件,并使用注入区域修改用户界面,请参阅 "可用操作" 表 了解所有可用的 API 及其相关的生命周期函数。

¥To add a settings link or section, use Redux reducers, hook into other plugins, and modify the user interface with injection zones, consult the "available actions" table for all available APIs and their associated lifecycle functions.

使用管理面板注册插件

¥Registering the plugin with the admin panel

🤓 v3/v4 比较

Strapi v3 插件通过使用 <my-plugin-name>/admin/src/index.js 文件中的 strapi.registerPlugin() 函数在管理面板中注册。

¥A Strapi v3 plugin is registered with the admin panel by using the strapi.registerPlugin() function in the <my-plugin-name>/admin/src/index.js file.

在 Strapi v4 中,该插件在 register() 生命周期函数 中注册。

¥In Strapi v4, the plugin is registered within the register() lifecycle function.

要将插件的前端注册更新到 Strapi v4:

¥To update the front-end registration of a plugin to Strapi v4:

  1. 如果该文件尚不存在,请在插件文件夹的根目录下创建一个 admin/src/index.js 文件。

    ¥If it does not already exist, create an admin/src/index.js file at the root of the plugin folder.

  2. <plugin-name>/admin/src/index.js 文件中,导出一个调用 register() 生命周期函数的函数,并将当前 Strapi 应用实例作为参数传递。

    ¥In the <plugin-name>/admin/src/index.js file, export a function that calls the register() lifecycle function, passing the current Strapi application instance as an argument.

  3. register() 生命周期函数体内,在应用实例上调用 registerPlugin() 函数,从 Strapi v3 配置对象中获取 nameid 键。

    ¥Inside the register() lifecycle function body, call the registerPlugin() function on the application instance, grabbing the name and id keys from the Strapi v3 configuration object.

  4. 通过将以下行添加到 <plugin-name>/strapi-admin.js 条目文件中,确保 Strapi 知道从 admin/src/index.js 导出的插件前端接口:

    ¥Make sure that Strapi is aware of the plugin's front-end interface exported from admin/src/index.js by adding the following line to the <plugin-name>/strapi-admin.js entry file:

    module.exports = require('./admin/src').default;
Example of a Strapi v4 plugin registration
./src/plugins/my-plugin/admin/src/index.js

import pluginId from './pluginId';

const pluginDescription = pluginPkg.strapi.description || pluginPkg.description;
const { name } = pluginPkg.strapi;

export default {
register(app) {
// executes as soon as the plugin is loaded
app.registerPlugin({
id: pluginId
name,
})
}
}
.src/plugins/my-plugin/strapi-admin.js

module.exports = require('./admin/src').default;

¥Adding a menu link

🤓 v3/v4 比较

Strapi v3 插件通过在插件注册期间导出 menu 对象来添加指向管理面板中菜单的链接。

¥A Strapi v3 plugin adds a link to the menu in the admin panel by exporting a menu object during the plugin registration.

在 Strapi v4 中,插件以编程方式添加菜单链接,并在 register 生命周期中调用 addMenuLink() 功能

¥In Strapi v4, a plugin adds a link to the menu programmatically with the addMenuLink() function called in the register lifecycle.

要迁移到 Strapi v4,请将 menu 密钥从 Strapi v3 配置对象传递到 app.addMenuLink(),并更新以下属性:

¥To migrate to Strapi v4, pass the menu key from the Strapi v3 configuration object to app.addMenuLink() with the following properties updated:

v3 中的属性名称和类型相当于 v4
destination(字符串)to(字符串)
label(字符串)intlLabel(字符串)
icon(字符串)

mainComponent(字符串)
<Icon />(反应组件)

基于 React 的图标组件可以在单独的文件中创建。

¥The React-based icon component can be created in a separate file.

Example of an PluginIcon component
./src/plugins/my-plugin/admin/src/components/PluginIcon/index.js

import React from "react";
import { Icon } from "@strapi/parts/Icon";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";



const PluginIcon = () => (


<Icon as={() => <FontAwesomeIcon icon="paint-brush" />} width="16px" />
);

export default PluginIcon;

在 Strapi v3 中,图标组件在 mainComponent 键上指定,在 Strapi v4 中,该组件作为动态导入传递到 app.addMenuLink() 函数。

¥In Strapi v3 the icon component is specified on the mainComponent key, in Strapi v4 the component is passed as a dynamic import to the app.addMenuLink() function.

Example of adding a menu link with a custom plugin icon component
./src/plugins/my-plugin/admin/src/index.js

import pluginId from './pluginId';
import pluginPermissions from './permissions';
import PluginIcon from './PluginIcon'



const pluginDescription = pluginPkg.strapi.description || pluginPkg.description;


const { name } = pluginPkg.strapi;

export default {
register(app) {
app.addMenuLink({
to: `/plugins/${pluginId}`,
icon: PluginIcon,
intlLabel: {
id: `${pluginId}.plugin.name`,
defaultMessage: 'My Plugin',
},
permissions: pluginPermissions.main,
Component: async () => {
const component = await import(/* webpackChunkName: "my-plugin-page" */ './pages/PluginPage');

return component;
},
});

app.registerPlugin({
description: pluginDescription,
id: pluginId
name
});
}
}

添加设置

¥Adding settings

🤓 v3/v4 比较

Strapi v3 插件通过在插件注册期间导出 settings 属性来添加设置部分。

¥A Strapi v3 plugin adds a settings section by exporting a settings property during the plugin registration.

在 Strapi v4 中,插件使用 设置接口 以编程方式添加设置部分。

¥In Strapi v4, a plugin adds a settings section programmatically using the Settings API.

要迁移到 Strapi v4,请根据你的 Strapi v3 插件的功能,使用下表查找要使用的适当的设置 API 方法,然后单击方法名称以转到其专用文档:

¥To migrate to Strapi v4, depending on what your Strapi v3 plugin does, use the following table to find the appropriate Settings API method to use, and click on the method name to go to its dedicated documentation:

行动方法
创建新的设置部分
并定义要包含在该部分中的新链接
createSettingsSection()
将链接添加到现有设置部分:
  • 单个链接
  • 多个链接

Example of creating a new settings section
./src/plugins/my-plugin/admin/src/index.js

import getTrad from './utils/getTrad';

register(app) {
// Create the plugin's settings section
app.createSettingSection(
// created section
{
id: pluginId,
intlLabel: {
id: getTrad('Settings.section-label'),
defaultMessage: 'My plugin settings',
},
},
// links
[
{
intlLabel: {
id: 'settings.page',
defaultMessage: 'Setting page 1',
},
id: 'settings',
to: `/settings/my-plugin/`,
Component: async () => {
const component = await import(
/* webpackChunkName: "my-plugin-settings-page" */ './pages/Settings'
);

return component;
},
permissions: [],
},

]
);

app.registerPlugin({
id: pluginId,
name,
});
},

添加 reducer

¥Adding reducers

🤓 v3/v4 比较

Strapi v3 插件通过在插件注册期间导出 reducers 属性来添加 reducer。

¥A Strapi v3 plugin adds reducers by exporting a reducers property during the plugin registration.

在 Strapi v4 中,插件使用 Reducer API 以编程方式添加 reducer。

¥In Strapi v4, a plugin adds reducers programmatically using the Reducers API.

要迁移到 Strapi v4,请确保使用 addReducers() 方法以编程方式添加 reducer。

¥To migrate to Strapi v4, make sure reducers are added programmatically with the addReducers() method.

Example of adding reducers
./src/plugins/my-plugin/admin/src/index.js

import myReducer from './components/MyCompo/reducer';
import myReducer1 from './components/MyCompo1/reducer';
import pluginId from './pluginId';



const reducers = {


[`${pluginId}_reducer`]: myReducer,
[`${pluginId}_reducer1`]: myReducer1,
};

export default {
register(app) {
app.addReducers(reducers);

app.registerPlugin({
id: pluginId,
name,
});
},
}
}

添加注入区

¥Adding injection zones

🤓 v3/v4 比较

Strapi v3 插件可以使用 Initializer 组件中的 registerField() 方法或 useStrapi 钩子将组件注入到内容管理器的编辑视图中。

¥A Strapi v3 plugin can inject components into the Content Manager's Edit view, using the registerField() method or the useStrapi hook within the Initializer component.

在 Strapi v4 中,插件可以使用 注入区 API 将组件注入到内容管理器的多个位置。

¥In Strapi v4, a plugin can inject components into several locations of the Content Manager using the Injection Zones API.

要迁移到 Strapi v4,请确保使用 Strapi v4 注入区 API 注入组件。根据组件应注入的位置,使用:

¥To migrate to Strapi v4, make sure components are injected using Strapi v4 Injection Zones API. Depending on where the component should be injected, use:

Example of injecting a component into the Content Manager's Edit view
./src/plugins/my-plugin/admin/src/index.js

import pluginId from './pluginId;
import Link from './components/Link'

export default {
bootstrap(app){
// insert a link in the 'right-links' zone of the Content Manager's edit view
app.injectContentManagerComponent('editView', 'right-links', {
name: `${pluginId}-link`,
Component: Link,
});
}
}

使用 Initializer 组件

¥Using the Initializer component

🤓 v3/v4 比较

在 Strapi v3 和 v4 中,创建插件时默认会生成 Initializer 组件。Initializer 可用于在应用加载时执行一些逻辑,例如在用户登录管理面板后分派操作。

¥In both Strapi v3 and v4, the Initializer component is generated by default when a plugin is created. Initializer could be used to execute some logic when the application is loading, for instance to dispatch an action after the user logs in into the admin panel.

在 Strapi v4 中,Initializer 组件代码已更改,并使用 useRefuseEffect React hook 来分派操作。

¥In Strapi v4, the Initializer component code has changed and uses the useRef and useEffect React hooks to dispatch actions.

Initializer 组件可用于在应用中存储全局状态,该状态将在使用 Redux 渲染应用之前加载。为了确保初始化程序组件已安装在应用中,请在使用 registerPlugin() 注册插件时将 isReady 键设置为 false

¥The Initializer component is useful to store a global state in the application, which will be loaded before the application is rendered using Redux. To make sure the Initializer component is mounted in the application, set the isReady key to false when registering the plugin with registerPlugin().

要迁移到 Strapi v4,请确保插件使用最新的 Initializer 代码,可以从以下代码示例中复制并粘贴该代码:

¥To migrate to Strapi v4, make sure the plugin uses the latest Initializer code, which can be copied and pasted from the following code example:

./src/plugins/my-plugin/admin/src/components/Initializer/index.js

import { useEffect, useRef } from 'react';
import PropTypes from 'prop-types';
import pluginId from '../../pluginId';



const Initializer = ({ setPlugin }) => {


const ref = useRef();
ref.current = setPlugin;

useEffect(() => {
ref.current(pluginId);
}, []);

return null;
};

Initializer.propTypes = {
setPlugin: PropTypes.func.isRequired,
};

export default Initializer;
Example of registering a plugin that uses the new Initializer component
./src/plugins/my-plugin/admin/src/index.js

export default {
register(app) {
app.registerPlugin({
id: pluginId,
initializer: Initializer,
isReady: false, // ensures the Initializer component is mounted in the application
name,
});
},
}
}

注册翻译

¥Registering translations

在 Strapi v4 中,前端插件接口可以导出 异步 registerTrads() 函数 用于注册翻译文件。

¥In Strapi v4, the front-end plugin interface can export an asynchronous registerTrads() function for registering translation files.

Example of translation registration
import { prefixPluginTranslations } from "@strapi/helper-plugin";

export default {
register(app) {
// register code...
},
bootstrap(app) {
// bootstrap code...
},
async registerTrads({ locales }) {
const importedTrads = await Promise.all(
locales.map((locale) => {
return import(
/* webpackChunkName: "[pluginId]-[request]" */ `./translations/${locale}.json`
)
.then(({ default: data }) => {
return {
data: prefixPluginTranslations(data, pluginId),
locale,
};
})
.catch(() => {
return {
data: {},
locale,
};
});
})
);

return Promise.resolve(importedTrads);
},
};