配置属性面板|飞书低代码平台

配置属性面板|飞书低代码平台

飞书低代码平台手册精选NaN-NaN-NaN
产品功能
概述
编写一个自定义组件,核心需要为其配置“属性”与“事件”面板。
通过配置“属性”面板,我们可以控制组件的名称、类型、默认值、是否为必填项等属性。
阅读前说明:下方文档将从场景切入,一一介绍属性面板的核心能力。不会囊括所有属性字段及其各个值的含义,属性面板详细配置查看:配置手册
安装
使用时,需要在应用的 components 目录下,安装 @byted-apaas/designer-react
npm i -S @byted-apaas/designer-react@latestt
如果是通过 ae component create创建的组件,会自动完整安装,无需再单独安装。
使用
(一)基本使用
属性声明
import { IMeta } from '@byted-apaas/designer-react';
const meta: IMeta = [
props: [
{
name: 'content',
type: 'String',
title: '按钮文字',
description: '我是一个按钮',
defaultValue: '按钮',
tooltip: '按钮的tooltip内容',
required: true,
// disabled: true
}
];
export default meta;
250px|700px|reset
image.png
下面对以上 8 个基础属性进行说明
字段
作用
name
属性唯一标识
type
属性类型,平台目前支持 String、Number、Boolean、Array 、Object、Void、Event、SlotFunction。本文中会涉及到所有类型的基本用法。
title
属性名称
description
属性描述
defaultValue
属性默认值
disabled
是否禁用,默认为 false
tooltip
属性名称悬浮提示
required
内置必填校验,默认为 false 即不做校验,如设置成 true,会在表单项组件失焦时自动校验值是否为空
更多字段
查看了解:类型定义
属性消费
对属性进行声明后,我们便可以在自定义组件内部使用 props :
import { Button } from '@universe-design/react';
export interface Props {
content: string;
}
export default function CustomButton(
props: Props,
): JSX.Element {
const { content } = props;
console.log(props); // 打印props,{ content: "按钮"}
return
<div>
<Button>{content}</Button>
</div>
}
此时修改按钮文字为“按钮new”,可以发现页面上也同步更新了:
250px|700px|reset
image.png
(二)高级特性
响应式联动
联动是个非常常见的需求,即需要属性 A 根据属性 B 做出一些响应,比如:控制显示隐藏、计算值等。此处提供了两种表达方式,分别是:插值表达响应式函数表达
  1. 函数表达
在响应式函数表达中,在 runner 中编写响应式逻辑,可以通过 scope.$values 获取到当前其他属性的值,当响应式逻辑中使用到的属性的值发生改变时,会自动执行runner函数进行重新计算。
比如我们新增一个属性 num1 ,由开关 num1Switch 控制其显隐。
import { IMeta } from '@byted-apaas/designer-react';
const meta: IMeta = [
props: [
{
name: 'num1Switch',
type: 'Boolean',
title: '开关-切换属性1',
defaultValue: false,
},
{
name: 'num1',
type: 'Number',
title: '属性1-由开关切换',
visible: {
type: 'Expression',
runner: scope => scope.$values.num1Switch
},
},
]
];
export default meta;
切换 num1Switch 的值,即可控制属性 num1 的显示和隐藏。
这里演示了对属性的 visible 字段应用联动,我们同样也可以对其他字段(类型中包含了 Expression 的字段)应用联动,包括:title、tooltip、description、required、visible、hidden、disabled、disabledDescription。
  1. 插值表达
插值表达是响应式函数表达的极简写法,当逻辑没有那么复杂,只用一个语句就可以描述时,可以直接用插值表达。在插值表达内,可以通过 $values 读取到整个属性配置面板中其他属性的值,等同于响应式函数表达的 scope.$values。
比如上面的函数表达,同样可以换成插值表达的写法:
import { IMeta } from '@byted-apaas/designer-react';
const meta: IMeta = [
props: [
{
name: 'num1Switch',
type: 'Boolean',
title: '开关-切换属性1',
defaultValue: false,
},
{
name: 'num1',
type: 'Number',
title: '属性1-由开关切换',
visible: '{{$values.num1Switch}}'
}
]
];
export default meta;
主动联动
响应式联动属于被动联动,除了响应式联动之外,平台还提供了主动联动方式,即由属性 A 主动更新属性 B 。
主动联动通过在setterProps中配置 onChange 实现,在onChange内可以通过 scope.$values.someProp = xxx 的方式去改变另一个属性的值。
此处不理解 setter 即 setterProps 的概念不用担心,可以先忽略,不影响理解主动联动的使用; setter的概念及使用会在后续章节 「输入控件 setter 」进行说明。
将以上响应式联动改为主动联动:由 num1Switch 主动控制 num1 的值。
import { IMeta } from '@byted-apaas/designer-react';
const meta: IMeta = [
props: [
{
name: 'num1Switch',
type: 'Boolean',
title: '开关-联动属性1',
defaultValue: false,
setterProps: {
onChange: {
type: 'Expression',
runner: scope => {
// onChange 是函数属性,这里需要返回一个函数
return value => {
// num1Switch 为 true,将 num1设置为1, 否则为0
scope.$values.num1 = value ? 1: 0
}
}
},
}
},
{
name: 'num1',
type: 'Number',
title: '属性1-由开关联动',
}
]
];
export default meta;
显示 & 隐藏
在前面的《响应式联动》小节,我们实现了对属性的显隐控制。配置一个属性置是否要隐藏,平台也提供了两种方式。(两种方式都能实现视图上的显隐控制,但是在数据层面有显著的区别,开发者可以根据实际情况选用)
  • visible:控制视图显隐 & 控制数据收集
  • 当为 false 时,视图隐藏,组件 props 中不存在此字段
  • 当为 true 时,视图显示,组件 props 中存在此字段
  • hidden:仅控制视图显隐
  • 当为 false 时,视图显示,组件 props 中存在此字段
  • 当为 true 时,视图隐藏,组件 props 中存在此字段
帮助理解:
visible:true | false 类似于 display:visible | none
hidden:true | false类似于 visibility: hidden | visible
💡
请勿同时使用 visible 和 hidden,在不同浏览器下可能会有不同表现。
来实践看看 visible 和 hidden 的区别:
import { IMeta } from '@byted-apaas/designer-react';
const meta: IMeta = [
props: [
{
type: 'Boolean',
name: 'switch1',
title: '开关1',
defaultValue: true
},
{
type: 'Number',
name: 'num1',
title: 'num1(visible控制)',
defaultValue: 1,
visible: '{{$values.switch1}}'
},
{
type: 'Boolean',
name: 'switch2',
title: '开关2',
defaultValue: true
},
{
type: 'Number',
name: 'num2',
title: 'num2(hidden控制)',
defaultValue: 2,
hidden: '{{!$values.switch2}}'
}
]
];
export default meta;
自定义校验
除通过配置required必填校验外,开发者也可通过 validator 属性自定义校验规则,定义如下:
/**
* 属性值校验方法,表单项值发生变化时自动触发该方法
* @param value 表单项的值
* @param formValues 所有属性的值
*/
validator?: (value: any, formValues: any) => boolean |string
import { IMeta } from '@byted-apaas/designer-react';
const meta: IMeta = [
props: [
{
name: 'num1',
type: 'Number',
title: '属性1',
validator: (value: number, formValues:any) => {
// return value > 10
return value > 10 ? '': '只支持大于10的数字'
}
}
]
];
export default meta;
  • 当返回 boolean 时,比如return value > 10,平台会在值为true时,使用错误提示的默认文案 “该字段不是一个合法的字段”;
250px|700px|reset
image.png
  • 当返回 string时,开发者可以自定义错误提示
250px|700px|reset
image.png
属性布局 decorator
以上用到的属性的布局方式都是左右结构,也可能出现内容展示空间不够的情况,如下图:
250px|700px|reset
image.png
这里我们可以更改其布局方式为 Block:
import { IMeta } from '@byted-apaas/designer-react';
const meta: IMeta = [
props: [
{
name: 'num1',
type: 'Number',
title: '属性1-由开关切换',
visible: '{{$values.num1Switch}}',
decorator: 'Block', // 设置布局方式为 Block
decoratorProps: {
boldTitle: true, // 标题加粗
divider: true // 分隔线
}
}
]
];
export default meta;
搭配布局方式,我们还可以设置 decoratorProps,目前支持「标题加粗」和「分隔线」。
250px|700px|reset
image.png
包括 Block 布局方式,平台一共提供了 4 种布局方式:"Inline" | "Plain" | "Block" | "Collapse",具体使用方法查看:Setter-布局方式
(三)输入控件 setter
系统setter
在属性配置中,平台会根据type字段的值,提供默认匹配的输入控件,比如 type = Number时,平台会默认提供如下控件NumberSetter:
250px|700px|reset
image.png
如果需要更丰富的控件,我们可以修改对应 setter 的配置 setterProps 来修改 setter 的默认配置。比如,以上使用到的 num1 是 Number 类型,那我们可以选择一个与 Number 类型匹配的 setter——NumberSetter,并配置相应的 setterProps。
setter 产出的结构要与属性的 type 匹配
import { IMeta } from '@byted-apaas/designer-react';
const meta: IMeta = [
props: [
{
name: 'num1',
type: 'Number',
title: '属性1-由开关切换',
visible: '{{$values.num1Switch}}',
decorator: 'Block', // 设置布局方式为 Block
decoratorProps: {
boldTitle: true, // 标题加粗
divider: true // 分隔线
},
setter: 'NumberSetter',
setterProps: {
placeholder: '请输入',
min: 1,
max: 100,
onlyNumber: true,
controls: false,
mode: 'stepper',
step: 0.1,
},
}
]
];
export default meta;
250px|700px|reset
image.png
平台还提供了许多常用的 setter 配置,详细使用查看:开发手册-官方 setter
自定义 setter
Setter 本质上就是一个普通的组件,该组件的 props 如下定义:
type SetterProps = {
value: any, // setter 的当前值,类型同定义的类型
onChange: (value: any) => void, // 变更当前值的事件
disabled: boolean, // 处于禁用态
error: boolean, // 处于错误态
}
我们可以实现一个自定义的 CustomInputSetter:
// customInputSetter.tsx
import { Input } from '@universe-design/react';
import { ISetterProps } from "@byted-apaas/designer-react";
type InputSetterProps = ISetterProps & {
placeholder?: string
}
export const CustomInputSetter: React.FC<InputSetterProps> = (props: InputSetterProps) => {
const {
value,
onChange,
error,
disabled,
placeholder = '请输入',
} = props;
return (
<Input
value={value}
disabled={disabled}
onChange={(e) => {
onChange(e.target.value)
}}
placeholder={placeholder}
error={error}
/>
)
}
CustomInputSetter.displayName = 'CustomInputSetter'
在属性中引用 CustomInputSetter :
import { CustomInputSetter } from './customInputSetter'
import { IMeta } from '@byted-apaas/designer-react';
const meta: IMeta = [
props: [
{
name: 'customSetter',
title: '自定义Setter',
type: 'String',
setter: CustomInputSetter,
}
]
];
export default meta;
250px|700px|reset
image.png
(四)属性分组
在章节「基本使用」我们有提到, propSetting 中配置的属性是以平铺形式输出到 props,而当属性过多时,属性面板展示和 props 使用都不够清晰,此时我们可以对属性进行分组。
纯 UI 分组
纯 UI 分组搭配 type: 'Void'和children字段使用。此时属性仅在面板展示时分组展示,但 props 输出值不分组(依然是平铺形式)。
import { IMeta,} from '@byted-apaas/designer-react';
const meta: IMeta = [
props: [
{
type: 'Void',
title: '属性分组',
decorator: 'Block',
decoratorProps: {
divider: true,
boldTitle: true
},
children: [
{
name: 'num1Switch',
type: 'Boolean',
title: '开关-切换属性1',
defaultValue: false,
},
{
name: 'num1',
type: 'Number',
title: '属性1-由开关切换',
visible: '{{$values.num1Switch}}',
}
]
}
]
];
export default meta;
属性面板展示
250px|700px|reset
image.png
props 数据格式(平铺格式不变)
{
num1Switch: false,
num1: ''
// ...其他属性
}
Object 数据分组
Object 数组结构分组搭配 type: 'Object'和properties使用。此时属性面板展示和 props 数据结构均会分组。
import { IMeta,} from '@byted-apaas/designer-react';
const meta: IMeta = [
props: [
{
type: 'Object',
title: '属性分组',
name: 'group',
decorator: 'Block',
decoratorProps: {
divider: true,
boldTitle: true
},
properties: [
{
name: 'num1Switch',
type: 'Boolean',
title: '开关-切换属性1',
defaultValue: false,
},
{
name: 'num1',
type: 'Number',
title: '属性1-由开关切换',
visible: '{{$values.num1Switch}}',
}
]
},
]
];
export default meta;
属性面板展示(与 UI 分组一样)
250px|700px|reset
image.png
props 数据格式
{
// ...其他属性
group: {
num1Switch: false,
num1: ''
}
}
Array 数据分组
我们还可以对属性进一步分组,搭配使用 type: 'Array'、setter: 'ListSetter'和 items 使用。
import { IMeta,} from '@byted-apaas/designer-react';
const meta: IMeta = [
props: [
{
type: 'Array',
title: '数组分组',
name: 'arr',
setter: "ListSetter",
defaultValue: [
{
num1Switch: false,
num1: 1
},
{
num1Switch: true,
num1: 2
}
],
item: {
type: 'Object',
properties: [
{
name: 'num1Switch',
type: 'Boolean',
title: '开关-切换属性1',
defaultValue: false,
},
{
name: 'num1',
type: 'Number',
title: '属性1-由开关切换',
visible: '{{$record.num1Switch}}',
}
]
},
decoratorProps: {
divider: true
}
}
]
];
export default meta;
平台 UI 展示
数据格式
{
// ...其他属性
arr: [
{
num1Switch: false,
num1: 1
},
{
num1Switch: true,
num1: 2
}
]
}
(五) Event 和 SlotFunction 类型
平台支持的类型包括 String、Number、Boolean、Array 、Object、Void、Event 和 SlotFunction。除了 Event和SlotFunction类型,其他类型均在以上文档内容有所体现。
  • 当 type 为SlotFunction,平台会认为该字段为插槽,详细使用查看插槽 slot
  • 当 type 为Event,平台会认为该字段为事件,详细使用查看事件与动作
(六) 属性表单表达式作用域变量(表单模型)
  • $form - 返回当前模型的顶层表单模型
  • $values - 返回当前模型的顶层表单模型的值
  • $lookup - 返回当前模型的父模型的记录值
  • $records - 返回当前模型的父数组模型的记录值
  • $record - 返回当前模型的记录值(数组)
  • $record.$index - 返回当前模型的记录值的模型索引
  • $record.$lookup - 返回当前模型的记录值的父模型的记录值
  • 这个可以一直向上索引
先进生产力和业务协同平台
联系我们立即试用

先进团队,先用飞书

欢迎联系我们,飞书效能顾问将为您提供全力支持
分享先进工作方式
输送行业最佳实践
全面协助组织提效
配置属性面板|飞书低代码平台
先进生产力和业务协同平台
联系我们立即试用
联系我们立即试用