数据可视化构建会碰到如下所示三类容器组件

lxf2023-03-17 18:51:01

数据可视化构建会碰到如下所示三类容器组件

  1. 简易器皿:以 children 容下子组件的器皿。
  2. 信用卡器皿:以 props.header 再加上 props.header 等多个扩展槽容下子组件的器皿。
  3. Tab 器皿:以 props.tabPanel[x] 等动态性总数扩展槽容下子组件的器皿。

画板本身就是一个容器组件,因此数据可视化构建离不了器皿。

另一方面,我们要容许给部件 props 传到 React 部件案例,但部件树是可序列化的 JSON 构造,所以需要一种理解形式,将一些特性转化为 React 部件案例发送给部件案例。

容器界定

一切部件都会成为容器组件,只需这将 props.childrenprops.footer 等所有特性做为 ReactNode 3D渲染。因而并不需要独特申明部件是否属于器皿,而只需将一些部件 Key 申明为 ReactNode 连接点。

Children

children 由于太常见因而独立注重出去,能够只能在在部件案例界定 children 特性,为是一个二维数组:

import { ComponentInstance } from "designer";

const componentTree: ComponentInstance = {
  componentName: "div",
  children: [
    {
      componentName: "input",
    },
  ],
};

对于这些部件,Designer 会把 children 界定的特性解读为部件案例,并真真正正分析为 React 案例传达给 props.children,因而部件3D渲染编码可以直接使用 children 3D渲染:

import { ComponentMeta } from "designer";

const divMeta: ComponentMeta = {
  componentName: "div",
  element: ({ children }) => <div>{children}</div>,
};

这类承诺的好处在于形象化当然,部件编码都没有关注到架构逻辑性,顺理成章完成了器皿作用。

treeLike 构造

只需把随意部件 props 界定为二维数组方式,而且包括 componentName,Designer 认为应当分析为 ReactNode。

如下边的事例,大家界定的 div 部件复位便会3D渲染一个 input 部件在 props.header 部位:

import { ComponentMeta } from "designer";

const divMeta: ComponentMeta = {
  componentName: "div",
  element: ({ header }) => <div>{header}</div>,
  defaultProps: {
    header: [
      {
        componentName: "input",
      },
    ],
  },
};

还可以在叙述部件树的时候直接写上相匹配 props 部位:

import { ComponentInstance } from "designer";

const componentTree: ComponentInstance = {
  componentName: "div",
  props: {
    header: [
      {
        componentName: "input",
      },
    ],
  },
};

这类承诺的好处在于直观地推动了随意 props key 为部件案例,但仍然存在限定,因而 Designer 还要适用一种客户 100% 控制的声明式界定:propTypes

PropTypes

在部件元信息 propTypes 属性定义更具体的器皿扩展槽部位,例如:

const tabMeta = {
  componentName: "tab",
  propTypes: {
    tabs: [
      {
        panel: "element",
      },
    ],
  },
};

因此当部件案例如下所示界定时:

const componentInstance = {
  componentName: "tab",
  props: {
    tabs: [
      {
        title: "tab1",
        panel: {
          componentName: "card",
        },
      },
      {
        title: "tab2",
        panel: {
          componentName: "text",
        },
      },
    ],
  },
};

部件拿到手的 props.tabs[0].panel 就是一个能直接3D渲染的 React 部件案例,毕竟在 propTypes 定义了 tabs[].panel 途径是一个部件案例。

这样设计应该考虑部件树赋值问题,由于部件案例部位界定在部件元信息上,因而只靠部件树没法做赋值(由于赋值父节点时,不融合 componentMeta 就无法确认什么 props 位置在子组件案例),那样会引发几个问题:

  1. 赋值部件比较麻烦,极端情况下,假如很多部件是远程控制登记注册的三方部件,也会导致必须一层层串行通信远程控制获取部件案例,造成赋值全过程减缓。
  2. 更极端场景是,当部件版本更新造成 propTypes 转变,一些本来并不是部件案例位置变成了部件案例,或是相反,这时获取全新部件元信息载入的 propTypes 就真是不对的。

由于以上两个缘故,实现方案应当是把部件元信息界定的 propTypes 复制一份到部件案例,这样就能光凭部件树本身来赋值部件树了,并且界定在部件树上 propTypes 一定相匹配现阶段部件树的结构。

汇总

我们可以通过 children 与 props 上 treeLike 这俩承诺,完成了业务流程基本上够用的器皿界定水平,光凭这俩承诺就能实现绝大多数器皿必须效果。

propTypes 界定补齐了承诺扩展性的缺陷,让 props 一切部位都会变成部件案例,只要付出附加界定 propTypes 代价。

阅读文章到了,我相信你早已理解到,数据可视化构建其实不存在容器组件这个概念,因为这部件之所以成为器皿,只是由于它的某一 prop 属性部件案例,不过它正好将这个特性3D渲染到某一个部位(甚至用 createPortal 初始化到另一个 dom 连接点),因此它仅仅只是一种 prop 属性反映,所以对容器组件,我们并没有设计方案一种新 type,反而是容许随意部位属性定义为案例。

下一节我们也会详细介绍为部件元信息加上取数与挑选联动的勾子,让筛选器 查看情景能够轻松被完成。

探讨地点是:选读《容器组件设计》· Issue #468 · dt-fe/weekly

如果你想要参与讨论,请 点击这里,每星期都有新主题风格,礼拜天或周一公布。前面选读 - 替你挑选比较靠谱的具体内容。

版权声明:随意转截-非商用-非衍化-维持落款(创意共享 3.0 许可证书)