diff --git a/docs/zh-CN/extend/custom-react.md b/docs/zh-CN/extend/custom-react.md
index b37d9be25..96cf65836 100644
--- a/docs/zh-CN/extend/custom-react.md
+++ b/docs/zh-CN/extend/custom-react.md
@@ -58,7 +58,8 @@ import * as React from 'react';
import {Renderer} from 'amis';
@Renderer({
- type: 'my-renderer'
+ type: 'my-renderer',
+ autoVar: true // amis 1.8 之后新增的功能,自动解析出参数里的变量
})
class CustomRenderer extends React.Component {
render() {
@@ -72,7 +73,8 @@ class CustomRenderer extends React.Component {
```javascript
Renderer({
- type: 'my-renderer'
+ type: 'my-renderer',
+ autoVar: true
})(CustomRenderer);
```
@@ -148,6 +150,26 @@ class CustomRenderer extends React.Component {
- `node` 子节点。
- `props` 可选,可以通过此对象跟子节点通信等。
+### 属性支持变量
+
+> 1.8.0 及以上版本新增配置,之前版本需要调用 amis 里的 resolveVariableAndFilter 方法
+
+前面的例子中组件参数都是静态的,但因为配置了 `autoVar: true`,使得所有组件参数将自动支持变量,比如下面例子中的 `tip` 在组件内拿到的将是解析后的值
+
+```json
+{
+ "type": "page",
+ "data": {
+ "myVar": "var"
+ },
+ "title": "自定义组件示例",
+ "body": {
+ "type": "my-renderer",
+ "tip": "${myVar}"
+ }
+}
+```
+
### 表单项的扩展
以上是普通渲染器的注册方式,如果是表单项,为了更简单的扩充,请使用 `FormItem` 注解,而不是 `Renderer`。 原因是如果用 `FormItem` 是不用关心:label 怎么摆,表单验证器怎么实现,如何适配表单的 3 种展现方式(水平、上下和内联模式),而只用关心:有了值后如何回显,响应用户交互设置新值。
diff --git a/examples/components/Form/Custom.jsx b/examples/components/Form/Custom.jsx
index f58bbad2a..da96bd95a 100644
--- a/examples/components/Form/Custom.jsx
+++ b/examples/components/Form/Custom.jsx
@@ -26,13 +26,16 @@ class MyFormItem extends React.Component {
}
@Renderer({
- test: /(^|\/)my\-renderer$/
+ test: /(^|\/)my\-renderer$/,
+ autoVar: true
})
class CustomRenderer extends React.Component {
render() {
- const {tip} = this.props;
- return (
-
{tip || '非 FormItem 类型的渲染器注册, 这种不能修改 form'}
+ const {tip, source} = this.props;
+ return source ? (
+ {`非 FormItem 类型的渲染器注册,通过变量获取 x 的值为:${source}`}
+ ) : (
+ {tip}
);
}
}
@@ -121,7 +124,8 @@ export default {
{
type: 'control',
body: {
- type: 'my-renderer'
+ type: 'my-renderer',
+ source: '${x}'
}
},
@@ -222,7 +226,7 @@ export default {
{
type: 'my-renderer',
- tip: '他能放 controls 里面,也能放外面。'
+ tip: '放表单外的情况'
}
]
};
diff --git a/src/SchemaRenderer.tsx b/src/SchemaRenderer.tsx
index b447915fb..629cd0dce 100644
--- a/src/SchemaRenderer.tsx
+++ b/src/SchemaRenderer.tsx
@@ -23,6 +23,7 @@ import {SimpleMap} from './utils/SimpleMap';
import type {RendererEvent} from './utils/renderer-event';
import {observer} from 'mobx-react';
import {isAlive} from 'mobx-state-tree';
+import {isPureVariable, resolveVariableAndFilter} from './utils/tpl-builtin';
interface SchemaRendererProps extends Partial {
schema: Schema;
@@ -102,7 +103,7 @@ class BroadcastCmpt extends React.Component {
}
render() {
- const {component: Component, rootStore, ...rest} = this.props;
+ const {component: Component, rootStore, autoVar, ...rest} = this.props;
const visible = isAlive(rootStore)
? rootStore.visibleState[rest.$schema.id || rest.$path]
: true;
@@ -114,19 +115,33 @@ class BroadcastCmpt extends React.Component {
if (disable) {
(rest as any).disabled = true;
}
+ const props = {...rest};
+
+ // 自动解析变量模式,主要是方便直接引入第三方组件库,无需为了支持变量封装一层
+ if (autoVar) {
+ for (const key of Object.keys(rest.$schema)) {
+ if (typeof props[key] === 'string') {
+ props[key] = resolveVariableAndFilter(
+ props[key],
+ props.data,
+ '| raw'
+ );
+ }
+ }
+ }
// 函数组件不支持 ref https://reactjs.org/docs/refs-and-the-dom.html#refs-and-function-components
return visible !== false ? (
isClassComponent ? (
) : (
@@ -414,6 +429,7 @@ export class SchemaRenderer extends React.Component {
ref={this.refFn}
render={this.renderChild}
component={Component}
+ autoVar={renderer.autoVar}
/>
);
diff --git a/src/factory.tsx b/src/factory.tsx
index e5adaf78e..15d0bf2f9 100644
--- a/src/factory.tsx
+++ b/src/factory.tsx
@@ -70,6 +70,7 @@ export interface RendererBasicConfig {
weight?: number; // 权重,值越低越优先命中。
isolateScope?: boolean;
isFormItem?: boolean;
+ autoVar?: boolean; // 自动解析变量
// [propName:string]:any;
}