本地项目启动成功后,就特别好奇中间区域的数据是如何接收?如何处理?最后又如何回传到别的地方?
入口packages/react/src/widgets/ComponentTreeWidget/index.tsx
export const ComponentTreeWidget: React.FC<IComponentTreeWidgetProps> =
observer((props: IComponentTreeWidgetProps) => {
const tree = useTree()
const prefix = usePrefix('component-tree')
const designer = useDesigner()
const dataId = {}
if (designer && tree) {
dataId[designer?.props?.nodeIdAttrName] = tree.id
}
useEffect(() => {
GlobalRegistry.registerDesignerBehaviors(props.components)
}, [])
return (
<div
style={{ ...props.style, ...tree?.props?.style }}
className={cls(prefix, props.className)}
{...dataId}
>
<DesignerComponentsContext.Provider value={props.components}>
<TreeNodeWidget node={tree} />
</DesignerComponentsContext.Provider>
</div>
)
}
props: 接收了一个components!components 接收的大抵就是这样子的数据,避免我们阅读分支太多,我们暂时不去细找它这里如何实现等。我们只需要明白这里是我们的数据来源
Input.Behavior = createBehavior(
{
name: 'Input',
extends: ['Field'],
selector: (node) => node.props['x-component'] === 'Input',
designerProps: {
propsSchema: createFieldSchema(AllSchemas.Input),
},
designerLocales: AllLocales.Input,
},
{
name: 'Input.TextArea',
extends: ['Field'],
selector: (node) => node.props['x-component'] === 'Input.TextArea',
designerProps: {
propsSchema: createFieldSchema(AllSchemas.Input.TextArea),
},
designerLocales: AllLocales.TextArea,
}
)
Input.Resource = createResource(
{
icon: 'InputSource',
elements: [
{
componentName: 'Field',
props: {
type: 'string',
title: 'Input',
'x-decorator': 'FormItem',
'x-component': 'Input',
},
},
],
},
{
icon: 'TextAreaSource',
elements: [
{
componentName: 'Field',
props: {
type: 'string',
title: 'TextArea',
'x-decorator': 'FormItem',
'x-component': 'Input.TextArea',
},
},
],
}
)
从之前上述代码中 我们可以看到组件最终渲染了一个自定义组件 并且传了node={tree} 这个
值、所以我们就需要关注一下 const tree = useTree() 这个hooks做了什么事情呢
// 这里是最根部的一个useTree 处理逻辑了
/**
* 1、生成treeNode 节点【最主要做的事】
* 2、展示区容器
*
**/
export const useWorkspace = (id?: string): Workspace => {
// 生成treeNode===>design
const designer = useDesigner()
// 区分工作区【表单、表格...】 默认为Form
const workspaceId = id || useContext(WorkspaceContext)?.id
if (workspaceId) {
// 寻找对应工作展示区域【json,代码,控件】
return designer.workbench.findWorkspaceById(workspaceId)
}
// 默认工作区为标签展示
if (globalThisPolyfill['__DESIGNABLE_WORKSPACE__'])
return globalThisPolyfill['__DESIGNABLE_WORKSPACE__']
// 兜底处理
return designer.workbench.currentWorkspace
}
const designer = useDesigner() 创建一个表单容器
useEffect(() => { GlobalRegistry.registerDesignerBehaviors(props.components) }, []) 注册
dataId[designer?.props?.nodeIdAttrName] = tree.id id匹配
DesignerComponentsContext组件使用react得createContext
<DesignerComponentsContext.Provider value={props.components}>
<TreeNodeWidget node={tree} /> // 节点逻辑
</DesignerComponentsContext.Provider>