概述

概念说明
UI Schema用于定义页面的结构和布局的 JSON 格式的配置文件。

一. 编写 Schema 组件

通过配置 x-component 将已注册的组件渲染出来

1import { Application, Plugin, SchemaComponent } from '@tachybase/client'
2import React from 'react'
3
4const HelloComponent = () => <h1>Hello World!</h1>
5
6const HelloPage = () => {
7  return (
8    <SchemaComponent
9      schema={{
10        name: 'hello',
11        type: 'void',
12        'x-component': 'HelloComponent',
13      }}
14    />
15  )
16}
17
18class PluginHello extends Plugin {
19  async load() {
20    this.app.addComponents({
21      HelloComponent,
22    })
23
24    this.router.add('hello', {
25      path: '/',
26      Component: HelloPage,
27    })
28  }
29}
30
31const app = new Application({
32  router: {
33    type: 'memory',
34  },
35  plugins: [PluginHello],
36})
37
38export default app.getRootComponent()

二. 初始化生成 Schema 组件

通过配置 x-initializer 将新的组件插入到已存在的 Schema 的相邻位置

1import {
2  Application,
3  CardItem,
4  Grid,
5  Plugin,
6  SchemaComponent,
7  SchemaInitializer,
8  SchemaInitializerItem,
9  useSchemaInitializer,
10  useSchemaInitializerItem,
11} from '@tachybase/client'
12import React from 'react'
13
14const HelloComponent = () => <h1>Hello World!</h1>
15
16const myInitializer = new SchemaInitializer({
17  name: 'myInitializer',
18  //  按钮标题标题
19  title: 'Add block',
20  wrap: Grid.wrap,
21  items: [
22    {
23      name: 'demo1',
24      title: 'Hello block',
25      Component: () => {
26        const itemConfig = useSchemaInitializerItem()
27        // 调用插入功能
28        const { insert } = useSchemaInitializer()
29        const handleClick = () => {
30          insert({
31            type: 'void',
32            'x-component': 'HelloComponent',
33          })
34        }
35        return (
36          <SchemaInitializerItem
37            title={itemConfig.title}
38            onClick={handleClick}
39          ></SchemaInitializerItem>
40        )
41      },
42    },
43  ],
44})
45
46const HelloPage = () => {
47  return (
48    <div>
49      <SchemaComponent
50        schema={{
51          name: 'hello',
52          type: 'void',
53          'x-component': 'Grid',
54          'x-initializer': 'myInitializer',
55        }}
56      />
57    </div>
58  )
59}
60
61class PluginHello extends Plugin {
62  async load() {
63    this.app.addComponents({
64      Grid,
65      CardItem,
66      HelloComponent,
67    })
68    this.router.add('hello', {
69      path: '/',
70      Component: HelloPage,
71    })
72    this.app.schemaInitializerManager.add(myInitializer)
73  }
74}
75
76const app = new Application({
77  router: {
78    type: 'memory',
79  },
80  // 为了更好的展示 demo,直接将 designable 设置为 true
81  designable: true,
82  plugins: [PluginHello],
83})
84
85export default app.getRootComponent()

三. 为 Schema 添加设计器工具栏

通过配置 x-settings 为 Schema 组件提供参数配置器,设计器工具栏默认开启拖拽功能

1import React from 'react'
2import {  useFieldSchema } from '@tachybase/schema'
3import {
4
5  Application,
6  CardItem,
7  Grid,
8  Plugin,
9  SchemaComponent,
10  SchemaInitializer,
11  SchemaInitializerItem,
12  SchemaSettings,
13  useSchemaInitializer,
14  useSchemaInitializerItem,
15} from '@tachybase/client'
16
17
18const mySettings = new SchemaSettings({
19  name: 'mySettings',
20  items: [
21    {
22      name: 'remove',
23      type: 'remove',
24      componentProps: {
25        removeParentsIfNoChildren: true,
26      },
27    },
28  ],
29})
30
31const myInitializer = new SchemaInitializer({
32  name: 'MyInitializer',
33  //  按钮标题标题
34  title: 'Button Text',
35  wrap: Grid.wrap,
36  // 调用 initializer.render() 时会渲染 items 列表
37  items: [
38    {
39      name: 'demo1',
40      title: 'Demo1',
41      Component: () => {
42        const itemConfig = useSchemaInitializerItem()
43        // 调用插入功能
44        const { insert } = useSchemaInitializer()
45        const handleClick = () => {
46          insert({
47            type: 'void',
48            'x-settings': 'mySettings',
49            'x-decorator': 'CardItem',
50            'x-component': 'Hello',
51          })
52        }
53        return (
54          <SchemaInitializerItem
55            title={itemConfig.title}
56            onClick={handleClick}
57          ></SchemaInitializerItem>
58        )
59      },
60    },
61  ],
62})
63
64const HelloComponent = () => {
65  const schema = useFieldSchema()
66  return <h1>Hello, world! {schema.name}</h1>
67}
68
69const hello1 = Grid.wrap({
70  type: 'void',
71  'x-settings': 'mySettings',
72  'x-decorator': 'CardItem',
73  'x-component': 'HelloComponent',
74})
75
76const HelloPage = () => {
77  return (
78    <div>
79      <SchemaComponent
80        schema={{
81          name: 'root',
82          type: 'void',
83          'x-component': 'Grid',
84          'x-initializer': 'MyInitializer',
85          properties: {
86            hello1,
87          },
88        }}
89      />
90    </div>
91  )
92}
93
94class PluginHello extends Plugin {
95  async load() {
96    this.app.addComponents({ Grid, CardItem, HelloComponent })
97    this.app.schemaSettingsManager.add(mySettings)
98    this.app.schemaInitializerManager.add(myInitializer)
99    this.router.add('hello', {
100      path: '/',
101      Component: HelloPage,
102    })
103  }
104}
105
106const app = new Application({
107  router: {
108    type: 'memory',
109  },
110  designable: true,
111  plugins: [PluginHello],
112})
113
114export default app.getRootComponent()