React插槽组件,可将组件插入自定义位置

React插槽组件,可将组件插入自定义位置

5 个月前 · 来自专栏 React开发

这是最近一个月前写的一个组件,可以将读取的组件看作类似插件的方式加载到不同位置上渲染。已经在自己项目里使用了,感兴趣的朋友可以使用看看。

react-pluggable-vx

React Slot 组件。

安装

npm install --save @gulibs/react-pluggable-vx

or

yarn add @gulibs/react-pluggable-vx

使用

编写需要放入插槽的组件

组件其实和普通 React 组件无异,在需要事件通信时可能需要使用到 PluginProvided .

header.tsx

import React from "react";
import { PluginProvided, Slot } from "react-pluggable-vx";
const Header: React.FC<PluginProvided> = ({ eventHandler }) => {
  const handleClick = () => {
    eventHandler.send("changeText", "你好呀", "heihei");
  return (
    <div onClick={handleClick}>
      <h3>Header Component</h3>
      <Slot name="header-content" />
export default Header;

headerContent.tsx

import React, { useState } from "react";
import { PluginProvided } from "react-pluggable-vx";
const HeaderContent: React.FC<PluginProvided> = ({ eventHandler }) => {
  const [text, setText] = useState("Test Plugin");
  eventHandler.subscribe<
    (text: string, other: string, obj: { text: string }) => void
  >("changeText", (text, other, obj) => {
    console.log("text:", text, ",other:", other, ",obj:", obj);
    setText(text);
  return <div>{text}</div>;
export default HeaderContent;

配置文件 ts

它可以帮助你导入所有的组件,须指定文件夹和需要导入的文件相对路径。

config.ts

import { defineConfig } from "react-pluggable-vx";
export default defineConfig({
  // 导入想要目录内所有*.tsx插件
  modules: import.meta.glob("./pluggable/**/*.tsx"),
  plugins: [
      name: "header",
      alias: "01",
      component: "./pluggable/Header/header",
      name: "header-content",
      component: "./pluggable/test",

编写插槽

App.tsx

import React from "react";
import { PluggableProvider, Slot } from "react-pluggable-vx";
import config from "./config";
const App: React.FC = () => {
  return (
    <PluggableProvider config={config}>
      <Slot name="header" />
      <Slot name="main" />
      <Slot name="footer" />
    </PluggableProvider>
export default App;

Hooks

useManager()

管理插件组件

使用

const manager = useManager();

示例

import React, { useEffect } from "react";
import { useManager } from "react-pluggable-vx";
const TestUseManager: React.FC = () => {
  const manager = useManager();
  useEffect(() => {
    // 还有许多api可以自行使用查看
    // 注册插件
    manager.registerPlugin({});
    // 注册多个插件
    manager.registerPlugins([
      // ... do something
  }, []);
  return (
      <Slot name="test" />

useEventHandler()

事件管理器

使用

const event = useEventHandler();

示例

import React, { useEffect } from "react";
import { useEventHandler } from "react-pluggable-vx";
// 插入到Slot receive的组件
const Receive: React.FC = () => {
  const event = useEventHandler();
  const [text, setText] = useState("");
  event.subscribe<(text: string) => void>("changeText", (text) => {
    setText(text);
  return <div>{text}</div>;
// 容器组件或者其他Slot中的组件
const TestUseEventHandler: React.FC = () => {
  const event = useEventHandler();
  const handleClick = () => {
    // 发送消息
    event.send("changeText", "Hello World");
  return (
      <button onClick={handleClick}>发送消息</button>
      <Slot name="receive" />

useRegister()

注册器,可以看做 useManager 的升级版, useManager 可以作为查询插件组件的作用,注册插件组件时不具备重新渲染的能力,在注册插件时可能会出现不更新子组件的情况,所以如果我们要动态注册插件组件时,可以使用这个 hook api 做到动态注册组件.

使用

const [keys, register] = useRegister();

示例

import React, { useEffect } from "react";
import { useRegister } from "react-pluggable-vx";
const TestUseRegister: React.FC = () => {
  const [keys, register] = useRegister();
  useEffect(() => {
    // 调用以下函数后会动态注册组件,并返回已注册的组件的keys
    // 注册插件
    register.registerPlugin({});
    // 注册多个插件
    register.registerPlugins([
      // ... do something
  }, []);
  return (
      <Slot name="test" />