开发进阶
使用三方依赖
编写的组件代码中,支持使用三方依赖,开发者只需要在代码中导入三方库,框架会根据代码中使用的依赖自动安装,不用自己手动安装。
举个例子,在代码中使用 antd 库。
import React from 'react';
import { Button } from 'antd';
export default function Demo({ title, context: { id } }) {
return (
<div data-id={id} className="title">
{title}
<Button type="primary">按钮</Button>
</div>
);
}
使用 material UI 组件
import React from 'react';
import Button from '@mui/material/Button';
export default function Demo({ title, context: { id } }) {
return (
<div data-id={id} className="title">
{title}
<Button variant="contained">按钮</Button>
</div>
);
}
使用 charts 图表库
import React from 'react';
import ReactECharts from 'echarts-for-react';
export default function Demo() {
return (
<ReactECharts
option={{
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
},
yAxis: {
type: 'value',
},
series: [
{
data: [120, 200, 150, 80, 70, 110, 130],
type: 'bar',
},
],
}}
notMerge={true}
lazyUpdate={true}
theme={'theme_name'}
/>
);
}
注意:导出的组件根元素必须有 data-id 这个属性,绑定 context 中 id 属性,这个属性是用来支持在编辑器中选择当前组件,修改组件属性使用的。
自定义属性
如果组件需要支持动态修改属性,也是支持的,下面给大家演示一下。
假设封装一个按钮组件,需要对外支持动态修改按钮文本、禁用、主题等功能。
这里使用 antd 的按钮为例,就不自己封装一个组件了。
import React from 'react';
import { Button } from 'antd';
export default function Demo({ text, disabled, type, context: { id } }) {
return (
<Button data-id={id} disabled={disabled} type={type}>
{text}
</Button>
);
}和普通 React 组件一样,可以从 props 中获取参数,绑定到组件中。
然后修改 config.js 文件
/**
* 组件配置和属性值,默认需要导出一个模块
*/
export default {
// 组件属性配置JSON
attrs: [{
type: 'Title',
label: '基础配置',
name: 'base',
},
{
type: 'Input',
label: '文本',
name: 'text',
},
{
type: 'Switch',
label: '禁用',
name: 'disabled',
},
{
type: 'Select',
label: '类型',
name: 'type',
props: {
options: [{
label: '默认',
value: 'default'
},
{
label: '主要',
value: 'primary'
},
],
},
},
],
config: {
// 组件默认属性值
props: {
text: 'hello',
disabled: false,
type: 'default',
},
// 组件样式
style: {},
api: {},
},
// 组件事件
events: [],
methods: [],
};这里的代码对应右侧的配置表单

attrs 表示当前组件对外暴露的配置项
type 字段表示配置的组件类型
Title表示标题Variable表示支持绑定变量Input表示文本输入框InputNumber表示数字输入框Select表示下拉框Switch表示切换组件Json表示 json 输入框
这些名称和 antd form 表单组件名称保持一致。
label 表示当前配置的中文描述
name 表示当前配置的名称,和组件的 props 参数保持一致
config.props 配置对应组件参数默认值,比如现在按钮的默认文本是 hello
如果想让组件的某个属性,绑定动态变量,可以把类型设置为 Variable ,比如把上面的按钮文本支持绑定变量。把 type 的值由 Input 改为 Variable 就行了。

暴露方法
如果组件需要对外暴露方法在事件流里调用,可以使用 react 中的 useImperativeHandle 对外暴露方法。
举个例子:上面的按钮对外导出一个开始 loading 方法。
修改代码如下
import React, {
useState,
useImperativeHandle
} from 'react';
import { Button } from 'antd';
export default function Demo(
{ text, disabled, type, context: { id } },
ref,
) {
const [loading, setLoading] = useState(false);
useImperativeHandle(ref, () => {
return {
startLoading: () => {
setLoading(true);
},
};
});
return (
<Button
data-id={id}
disabled={disabled}
type={type}
loading={loading}
>
{text}
</Button>
);
}给 config.js 中的 methods 属性添加值
/**
* 组件配置和属性值,默认需要导出一个模块
*/
export default {
// 组件属性配置JSON
attrs: [{
type: 'Title',
label: '基础配置',
name: 'base',
},
{
type: 'Input',
label: '文本',
name: 'text',
},
{
type: 'Switch',
label: '禁用',
name: 'disabled',
},
{
type: 'Select',
label: '类型',
name: 'type',
props: {
options: [{
label: '默认',
value: 'default'
},
{
label: '主要',
value: 'primary'
},
],
},
},
],
config: {
// 组件默认属性值
props: {
text: 'hello',
disabled: false,
type: 'default',
},
// 组件样式
style: {},
api: {},
},
// 组件事件
events: [],
methods: [{
title: '开始loading',
name: 'startLoading' // 这里要和导出的方法名保持一致
}],
};在编辑器的事件流里可以选到这个组件方法了


暴露事件
自定义组件也支持对外暴露事件
举个例子:
按钮对外暴露点击事件绑定事件流
import React, { useState, useImperativeHandle } from 'react';
import { Button } from 'antd';
export default function Demo(
{
text,
disabled,
type,
onClick,
context: { id }
},
ref
) {
const [loading, setLoading] = useState(false);
useImperativeHandle(ref, () => {
return {
startLoading: () => {
setLoading(true);
}
}
})
return (
<Button
data-id={id}
disabled={disabled}
type={type}
loading={loading}
onClick={() => {
onClick && onClick();
}}
>
{text}
</Button>
);
}修改 config.js 文件
/**
* 组件配置和属性值,默认需要导出一个模块
*/
export default {
// 组件属性配置JSON
attrs: [{
type: 'Title',
label: '基础配置',
name: 'base'
},
{
type: 'Variable',
label: '文本',
name: 'text'
},
{
type: 'Switch',
label: '禁用',
name: 'disabled'
},
{
type: 'Select',
label: '类型',
name: 'type',
props: {
options: [{
label: '默认',
value: 'default'
},
{
label: '主要',
value: 'primary'
}
]
}
},
],
config: {
// 组件默认属性值
props: {
text: "hello",
disbaled: false,
type: 'default',
},
// 组件样式
style: {},
api: {}
},
// 组件事件
events: [{
name: '点击事件',
value: 'onClick' // 这里和传入的事件名保持一致
}],
methods: [{
title: '开始loading',
name: 'startLoading' // 这里要和导出的方法名保持一致
}]
};在编辑器中给组件绑定点击事件

暴露数据
自定义组件还支持对外暴露数据,方便在脚本编辑器中使用。
可以使用 setCurComponentData 方法把数据暴露出去。
import React, { useState, useImperativeHandle } from 'react';
import { Button } from 'antd';
export default function Demo(
{
text,
disabled,
type,
onClick,
context: {
id,
setCurComponentData,
}
},
ref
) {
const [loading, setLoading] = useState(false);
useImperativeHandle(ref, () => {
return {
startLoading: () => {
setLoading(true);
}
}
})
return (
<Button
data-id={id}
disabled={disabled}
type={type}
loading={loading}
onClick={() => {
setCurComponentData('title', Date.now().toString())
onClick && onClick();
}}
>
{text}
</Button>
);
}修改 config.js 配置文件
/**
* 组件配置和属性值,默认需要导出一个模块
*/
export default {
// 组件属性配置JSON
attrs: [
{
type: 'Title',
label: '基础配置',
name: 'base'
},
{
type: 'Variable',
label: '文本',
name: 'text'
},
{
type: 'Switch',
label: '禁用',
name: 'disabled'
},
{
type: 'Select',
label: '类型',
name: 'type',
props: {
options: [
{ label: '默认', value: 'default' },
{ label: '主要', value: 'primary' }
]
}
},
],
config: {
// 组件默认属性值
props: {
text: "hello",
disbaled: false,
type: 'default',
},
// 组件样式
style: {},
api: {}
},
// 组件事件
events: [{
name: '点击事件',
value: 'onClick'
}],
methods: [{
title: '开始loading',
name: 'startLoading' // 这里要和导出的方法名保持一致
}],
exportKeys: [{ // [!code ++ ]
key: 'title', // 这个key对应setCurComponent方法的第一个参数 // [!code ++ ]
name: '标题'// [!code ++ ]
}]// [!code ++ ]
};编辑器中就可以在脚本编辑器中使用到组件暴露出来的变量
举个例子,让当前组件的标题字段绑定这个变量


点击按钮后,按钮的文本会自动变化

数据联动
自定义组件中可以使用 useData 获取编辑器中传入的数据源
举个例子:自定义一个下拉框组件,下拉框的数据源来源于编辑器。
import React from 'react';
import { Select } from 'antd';
export default function Demo(
{
context: {
id,
useData,
}
}
) {
// 可以调用refresh方法刷新数据
const { list = [], loading, refresh } = useData();
return (
<Select
data-id={id}
options={list}
loading={loading}
/>
);
}保存并预览

可以在右侧mock数据

可以在 config.js 里设置默认数据
/**
* 组件配置和属性值,默认需要导出一个模块
*/
export default {
// 组件属性配置JSON
attrs: [],
config: {
// 组件默认属性值
props: {},
// 组件样式
style: {},
api: {
source: [
{
"label": "选项1",
"value": 1
},
{
"label": "选项2",
"value": 2
},
{
"label": "选项3",
"value": 3
}
]
}
},
// 组件事件
events: [],
methods: [],
exportKeys: []
};在编辑器中可以使用其他数据源,比如模型。

拖放组件到内部
自定义组件支持把其他组件拖入到内部,把drop绑定到支持拖放的组件上,渲染children。
import React from 'react';
export default function Demo(
{
context: {
id,
drop
},
children
}
) {
return (
<div
data-id={id}
ref={drop}
>
{children}
</div>
);
}修改 config.js ,开启拖放
/**
* 组件配置和属性值,默认需要导出一个模块
*/
export default {
// 组件属性配置JSON
attrs: [],
config: {
// 组件默认属性值
props: {},
// 组件样式
style: {},
api: {}
},
// 组件事件
events: [],
methods: [],
exportKeys: [],
enableDrop: true,
};在编辑器里可以看到刚才开发的自定义支持拖放组件了

比如拖放一个基础表格到自定义组件中

样式
开发组件,可能会写样式,自定义组件中支持两种写样式的方式。 less 和 tailwindcss 。
less
index.jsx
import React from 'react';
export default function Demo(
{
context: {
id,
}
}
) {
return (
<div
data-id={id}
className="title"
>
hello
</div>
);
}index.less
@color: green;
.title {
color: @color;
}
tailwindcss
目前AI生成的代码对 tailwindcss 支持的比较成熟,所以我们自定义组件中也支持使用 tailwindcss 所有特性。
import React from 'react';
export default function Demo(
{
context: {
id,
}
}
) {
return (
<div
data-id={id}
className="text-red-500 hover:text-green-500"
>
hello
</div>
);
}
hover后

