# Technical Documentation: baidu/amis

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/baidu/amis)

### Overview (README.md)

<div align="center">
  <p>
    <img width="284" src="https://github.com/baidu/amis/raw/master/examples/static/logo.png">
  </p>

[文档（国内）](https://aisuda.bce.baidu.com/amis/) |
[文档（国外）](https://baidu.github.io/amis/) |
[可视化编辑器](https://aisuda.github.io/amis-editor-demo/) |
[amis-admin](https://github.com/aisuda/amis-admin) |
[爱速搭](https://aisuda.baidu.com/)

</div>

<div align="center">
  如流群：3395342 |
  如流群2：5511067|
</div>

<div align="center">





[](https://codecov.io/gh/baidu/amis)


</div>

前端低代码框架，通过 JSON 配置就能生成各种后台页面，极大减少开发成本，甚至可以不需要了解前端。

## 开发指南

以下是参与开发 amis 才需要看的，使用请看前面的文档。

> 如果 github 下载慢可以使用 [gitee](https://gitee.com/baidu/amis) 上的镜像。

推荐使用 node 12/14/16。npm 7+， 因为用到了 workspaces 功能。

```bash
# 安装项目 npm 依赖，在 node 12 下会有报错但不影响正常使用。
npm i --legacy-peer-deps

# 启动项目，等编译结束后通过 http://127.0.0.1:8888/examples/pages/simple 访问。
npm start
```

如果是开发编辑器，需要访问 `http://127.0.0.1:8888/packages/amis-editor/`

### 测试

> 注意：本地修改代码后，执行测试用例（`npm test --workspaces`）之前需要先执行`npm run build`完成编译，因为 jest 并不支持 TypeScript

```bash
# 安装依赖
npm i --legacy-peer-deps

# 执行构建
npm run build

# 执行测试用例
npm test --workspaces

# 测试某个用例
# <spec-name>为用例名称，比如inputImage
npm test --workspace amis -- -t <spec-name>

# 运行某个单测文件
./node_modules/.bin/jest packages/amis/__tests__/renderers/Form/buttonToolBar.test.tsx

# 运行某个单测文件里的某个例子
./node_modules/.bin/jest packages/amis/__tests__/renderers/Form/buttonToolBar.test.tsx -t 'Renderer:button-toolbar'

# 查看测试用例覆盖率
npm run coverage

# 更新 snapshot
npm run update-snapshot

# 更新单个 snapshot
# <spec-name>为用例名称，比如inputImage
npm run update-snapshot --workspace amis -- -t  <spec-name>
```

### 发布版本

```bash
# 发布内部 registry
npm run publish

# 发布外网环境
# 先通过一下命令设置版本号
npm run version
npm run release
```

### 如何贡献

请使用分支开发，首先创建分支

    git checkout -b feat-xxx

开发提交后使用 `git push --set-upstream origin feat-xxx` 创建远程分支。

然后通过系统提示的 https://github.com/xxx/amis/pull/new/feat-xxx 链接来提交 PR。

请采用 typescript 编写，所有合理的改动、新的公用渲染器、用例或者文档的提交都会被接收。

## 贡献者

<a href="https://github.com/baidu/amis/graphs/contributors"><img src="https://opencollective.com/amis/contributors.svg?width=890" /></a>

## 低代码平台

amis 只能实现前端低代码，如果需要完整的低代码平台推荐使用[爱速搭](https://aisuda.baidu.com/)。

---

### Zh CN Index (`docs/zh-CN/index.md`)

---
title: 介绍
description: 介绍
type: 0
group: 💡 概念
menuName: 介绍
icon:
order: 8
---

## 什么是 amis

amis 是一个低代码前端框架，它使用 JSON 配置来生成页面，可以减少页面开发工作量，极大提升效率。

## 为什么要做 amis？

在经历了十几年的发展后，前端开发变得越来越复杂，门槛也越来越高，要使用当下流行的 UI 组件库，你必须懂 `npm`、`webpack`、`react/vue`，必须熟悉 `ES6` 语法，最好还了解状态管理，比如 `Redux`，如果没接触过函数式编程，光入门都很费劲，而入门之后会发现它还有巨大的 [生态](https://github.com/markerikson/redux-ecosystem-links)，相关的库有 **2347** 个，很多功能相似，挑选成本高。

然而前端技术的发展不会停滞，等学完这些后可能会发现大家都用 `Hooks` 了、某个打包工具取代 `Webpack` 了……

而有时候其实只想做个普通的增删改查界面，用于信息管理，类似下面这种：

```
/* Detailed source-code truncated for AI context efficiency. */
```

这个界面虽然用 `Bootstrap` 及各种前端 UI 库也能做出个大概，但仔细观察会发现它有大量细节功能，比如：

- 可以对数据做筛选
- 有按钮可以刷新数据
- 编辑单行数据
- 批量修改和删除
- 按某列排序
- 可以隐藏某些列
- 可以调整列顺序
- 自动生成顶部查询区域
- 可调整列宽度
- 开启整页内容拖拽排序
- 表格有分页（页数还能同步到地址栏，不过这个例子中关了）
- 有数据汇总
- 支持导出 Excel
- 「渲染引擎」那列的表头有提示文字
- 鼠标移动到「平台」那列的内容时还有放大镜符号，可以展开查看更多
- 如果往下拖动还有首行冻结来方便查看表头（因为文档页面的限制，这个功能在这里看不出来）

全部实现这些需要大量的代码。

但可以看到，用 amis 只需要 **157** 行 JSON 配置（其中 47 行只有一个括号），你不需要了解 `React/Vue`、`Webpack`，甚至不需要很了解 `JavaScript`，即便没学过 amis 也能猜到大部分配置的作用，只需要简单配置就能完成所有页面开发。

这正是建立 amis 的初衷，我们认为：**对于大部分常用页面，应该使用最简单的方法来实现**，甚至不需要学习前端框架和工具。

## 用 JSON 写页面有什么好处

为了实现用最简单方式来生成大部分页面，amis 的解决方案是基于 [JSON](https://baike.baidu.com/item/JSON) 来配置，它的独特好处是：

- **不需要懂前端**：在百度内部，大部分 amis 用户之前从来没写过前端页面，也不会 `JavaScript`，却能做出专业且复杂的后台界面，这是所有其他前端 UI 库都无法做到的；
- **不受前端技术更新的影响**：百度内部最老的 amis 页面是 6 年多前创建的，至今还在使用，而当年的 `Angular/Vue/React` 版本现在都废弃了，当年流行的 `Gulp` 也被 `Webpack` 取代了，如果这些页面不是用 amis，现在的维护成本会很高；
- **享受 amis 的不断升级**：amis 一直在提升细节交互体验，比如表格首行冻结、下拉框大数据下不卡顿等，之前的 JSON 配置完全不需要修改；
- 可以 **完全** 使用 [可视化页面编辑器](https://aisuda.github.io/amis-editor-demo/) 来制作页面：一般前端可视化编辑器只能用来做静态原型，而 amis 可视化编辑器做出的页面是可以直接上线的。

## amis 的其它亮点

- **提供完整的界面解决方案**：其它 UI 框架必须使用 JavaScript 来组装业务逻辑，而 amis 只需 JSON 配置就能完成完整功能开发，包括数据获取、表单提交及验证等功能，做出来的页面不需要经过二次开发就能直接上线；
- **大量内置组件（120+），一站式解决**：其它 UI 框架大部分都只有最通用的组件，如果遇到一些稍微不常用的组件就得自己找第三方，而这些第三方组件往往在展现和交互上不一致，整合起来效果不好，而 amis 则内置大量组件，包括了富文本编辑器、代码编辑器、diff、条件组合、实时日志等业务组件，绝大部分中后台页面开发只需要了解 amis 就足够了；
- **支持扩展**：除了低代码模式，还可以通过 [自定义组件](./extend/internal) 来扩充组件，实际上 amis 可以当成普通 UI 库来使用，实现 90% 低代码，10% 代码开发的混合模式，既提升了效率，又不失灵活性；
- **容器支持无限级嵌套**：可以通过嵌套来满足各种布局及展现需求；
- **经历了长时间的实战考验**：amis 在百度内部得到了广泛使用，**在 6 年多的时间里创建了 5 万页面**，从内容审核到机器管理，从数据分析到模型训练，amis 满足了各种各样的页面需求，最复杂的页面有超过 1 万行 JSON 配置。

## amis 不适合做什么？

使用 JSON 有优点但也有明显缺点，在以下场合并不适合 amis：

- **大量定制 UI**：JSON 配置使得 amis 更适合做有大量常见 UI 组件的页面，但对于面向普通客户（toC）的页面，往往追求个性化的视觉效果，这种情况下用 amis 就不合适，实际上绝大部分前端 UI 组件库也都不适合，只能定制开发。
- **极为复杂或特殊的交互**：
  - 有些复杂的前端功能，比如 可视化编辑器，其中有大量定制的拖拽操作，这种需要依赖原生 DOM 实现的功能无法使用 amis。
  - 但对于某些交互固定的领域，比如图连线，amis 后续会有专门的组件来实现。

## 阅读建议

- 如果你是第一次接触 amis，那么请 **务必认真阅读完概念部分**，它会让你对 amis 有个整体的认识
- 如果你已经掌握 amis 基本概念，且有一定的开发经验，需要参考 amis 组件相关文档的同学，那么请移步 [组件文档](../components/page)

## 让我们马上开始吧

点击页面底部的下一篇，继续阅读文档。

---

### Zh CN Components Index (`docs/zh-CN/components/index.md`)

---
title: 组件介绍
description:
type: 0
group: ⚙ 组件
menuName: 组件介绍
icon:
order: 21
---

从这个章节开始，我们将会介绍 amis 中内置的所有组件的使用方法

---

### Zh CN Style Index (`docs/zh-CN/style/index.md`)

---
title: 快速开始
---

示例有个[主题编辑器](../../examples/theme)，可以在线实时预览效果。

> 这是 1.1.0 版本中新增的功能

在 amis 中自定义样式有四种方式：

1. 使用 CSS 变量动态修改，通过这种方式修改大部分 amis 组件的样式，所有组件都会生效，注意这种方法不支持 IE11。
2. 使用辅助 class，可以对单个组件做定制修改。
3. 自己生成主题 CSS，可以修改所有配置，目前只能通过源码方式，请参考 `scss\themes\cxd.scss` 文件，修改变量后重新编译一个 css，需要注意这种方式在更新 amis 版本的时候最好重新编译，否则就会出现使用旧版 css 的情况，可能导致出错，因此不推荐使用。
4. `wrapper` 组件可以直接写内嵌 `style`。

本文主要介绍前两种方法：

## CSS 变量

在 page 下可以设置 cssVars 属性，通过它来动态修改 amis 内的 css 变量。

```schema
{
  "type": "page",
  "cssVars": {
    "--text-color": "#CD3632",
    "--primary": "#CD3632",
    "--primary-onHover": "#F23F3A",
    "--primary-onActive": "#BB312D"
  },
  "body": {
    "type": "form",
    "body": [
      {
        "type": "input-text",
        "label": "文本",
        "name": "text"
      },
      {
        "type": "input-password",
        "label": "密码",
        "name": "password"
      }
    ]
  }
}
```

具体有哪些变量请参考左侧的 [CSS 变量](css-vars) 说明。

## 辅助 class

辅助 class 参考自[tailwindcss](https://tailwindcss.com/), 做了精简，把一些不常用的剔除了，响应式方面只保留 pc 和手机两种，css 未压缩版本大概是 800K 左右，比 tailwind 要小很多。

使用方法：

- JS SDK
  - 引入 sdk 中的文件 `<link rel="stylesheet" href="sdk/helper.css" />`
- React
  - `import 'amis/lib/helper.css'`;

目前这个文件没有和主题文件合并在一起，用户可以选择性加载。

大部分 amis 组件都有 `className` 或者 `xxxClassName` 的配置，比如下面的配置给表单增加了边框、圆角和阴影

```schema: scope="body"
{
  "type": "form",
  "panelClassName": "border-solid border-2 border-blue-500 rounded-xl shadow-lg",
  "body": [
    {
      "type": "input-text",
      "className": "text-green-700",
      "label": "文本框",
      "name": "text"
    },
    {
      "type": "input-password",
      "label": "密码",
      "name": "password"
    }
  ]
}
```

还可以：

- 通过 `flex` `flex-shrink-0` 来设置布局方式。
- 通过 `bg-blue-100` `bg-white` 之类的类名设置背景色。
- 通过 `shadow-md` 设置投影。
- 通过 `rounded-xl` 设置圆角。
- 通过 `text-xl`、`font-medium` 设置字体大小粗细。
- 等等。。

具体用法请查看左边的文档列表。

---

### Zh CN Components Form Index (`docs/zh-CN/components/form/index.md`)

---
title: Form 表单
description:
type: 0
group: ⚙ 组件
menuName: Form 表单
icon:
order: 24
---

表单是 amis 中核心组件之一，主要作用是提交或者展示表单数据。

## 基本用法

最基本的用法是配置 [表单项](./formitem) 和 提交接口`api`。

如下我们配置姓名和邮箱表单项，并可以填写数据并提交给接口`/api/mock2/form/saveForm`。

```schema: scope="body"
{
    "type": "form",
    "api": "/api/mock2/form/saveForm",
    "body": [
      {
        "type": "input-text",
        "name": "name",
        "label": "姓名："
      },
      {
        "name": "email",
        "type": "input-email",
        "label": "邮箱："
      }
    ]
}
```

## 表单展示

### 默认模式

默认展示模式为文字表单项分行显示

```schema: scope="body"
{
    "type": "form",
    "api": "/api/mock2/form/saveForm",
    "body": [
      {
        "type": "input-text",
        "name": "name",
        "label": "姓名："
      },
      {
        "name": "email",
        "type": "input-email",
        "label": "邮箱："
      }
    ]
}
```

### 水平模式

水平模式，左右摆放，左右比率分配。

```schema: scope="body"
{
    "type": "form",
    "title": "水平模式",
    "mode": "horizontal",
    "body": [
      {
        "type": "input-email",
        "name": "email",
        "label": "邮箱",
        "required": true
      },
      {
        "type": "input-password",
        "name": "password",
        "label": "密码"
      },
      {
        "type": "checkbox",
        "name": "rememberMe",
        "label": "记住登录"
      }
    ]
}
```

可以配置`horizontal`属性，调整偏移量，格式如下：

```
"horizontal": {
    "left": 2,
    "right": 10,
    "offset": 2
}
```

```schema: scope="body"
{
    "type": "form",
    "title": "水平模式",
    "mode": "horizontal",
    "horizontal": {
      "left": 2,
      "right": 10,
      "offset": 2
    },
    "body": [
      {
        "type": "input-email",
        "name": "email",
        "label": "邮箱",
        "required": true
      },
      {
        "type": "input-password",
        "name": "password",
        "label": "密码"
      },
      {
        "type": "checkbox",
        "name": "rememberMe",
        "label": "记住登录"
      }
    ]
}
```

通过上面的配置可以看出来水平布局其实按比率分配的。实际上有时候固定左侧宽度更好看点。

```
"horizontal": {
    "leftFixed": true
}
```

也可以直接配置 'xs' | 'sm' | 'md' | 'lg' 来定义左侧 label 的宽度。

```schema: scope="body"
{
    "type": "form",
    "title": "水平模式",
    "mode": "horizontal",
    "horizontal": {
      "leftFixed": "sm"
    },
    "body": [
      {
        "type": "input-email",
        "name": "email",
        "label": "邮箱",
        "required": true
      },
      {
        "type": "input-password",
        "name": "password",
        "label": "密码"
      },
      {
        "type": "checkbox",
        "name": "rememberMe",
        "label": "记住登录"
      }
    ]
}
```

#### 两端对齐

有时表单内容需要两端对齐，可在 horizontal 中增加 justify 配置，注意只对内联控件生效

```schema: scope="body"
{
  "type": "container",
  "style": {
    "width": "300px",
  },
  "body": [
    {
      "type": "form",
      "title": "两端对齐",
      "mode": "horizontal",
      "horizontal": {
        "justify": true,
        "left": 3,
        "right": 9
      },
      "body": [
        {
          "type": "input-text",
          "name": "name",
          "label": "姓名",
          "required": true
        },
        {
          "type": "input-text",
          "name": "name",
          "label": "班级",
          "required": true
        },
        {
          "type": "switch",
          "name": "status",
          "inputClassName": "is-inline",
          "label": "是否在职",
          "onText": "在职",
          "offText": "非在职"
        }
      ]
    }
  ]
}
```

#### label 对齐模式

水平模式下 `labelAlign` 可以设置标签文本的对齐方式，支持`right`和`left`，默认为`right`。该属性的优先级：表单项 > 表单。

```schema: scope="body"
{
  "type": "form",
  "title": "label对齐模式",
  "mode": "horizontal",
  "labelAlign": "left",
  "body": [
    {
      "type": "input-email",
      "name": "email",
      "label": "邮箱",
      "labelAlign": "right",
      "required": true
    },
    {
      "type": "input-password",
      "name": "password",
      "label": "密码",
      "required": true
    }
  ]
}
```

### 内联模式

使用内联模式展现表单项

```schema: scope="body"
 {
    "type": "form",
    "title": "内联模式",
    "mode": "inline",
    "body": [
      {
        "type": "input-email",
        "name": "email",
        "label": "邮箱"
      },
      {
        "type": "input-password",
        "name": "password"
      },
      {
        "type": "checkbox",
        "name": "rememberMe",
        "label": "记住登录"
      },
      {
        "type": "submit",
        "label": "登录"
      }
    ]
  }
```

### 自定义 label 宽度

水平模式下 `labelWidth` 可以设置标签文本的自定义宽度，默认单位为`px`。该属性的优先级：表单项 > 表单。

```schema: scope="body"
{
  "type": "form",
  "title": "label对齐模式",
  "mode": "horizontal",
  "labelWidth": 120,
  "body": [
    {
      "type": "input-email",
      "name": "email",
      "label": "邮箱",
      "labelWidth": 200,
      "required": true
    },
    {
      "type": "input-password",
      "name": "password",
      "label": "密码",
      "required": true
    },
    {
      "type": "input-text",
      "name": "address",
      "label": "地址",
      "mode": "inline"
    },
    {
      "type": "input-text",
      "name": "mailCode",
      "label": "邮编",
      "mode": "inline",
      "labelWidth": 80
    },
    {
      "type": "radios",
      "name": "mailCode",
      "label": "性别",
      "mode": "row",
      "options": [
        {
          "label": "Male",
          "value": "male"
        },
        {
          "label": "Female",
          "value": "female"
        }
      ]
    }
  ]
}
```

### 实现一行展示多个表单项

有两种方法，一个是通过 `columnCount` 来控制表单显示几列

```schema: scope="body"
 {
    "type": "form",
    "title": "内联模式",
    "columnCount": 2,
    "body": [
      {
        "type": "input-email",
        "name": "email",
        "label": "邮箱",
        "required": true
      },
      {
        "type": "input-password",
        "name": "password",
        "label": "密码"
      }
    ]
  }
```

另一个方法是使用 group，它能实现每行显示不同列数，以及不同列的宽度分配情况，可以实现更灵活的控制

```
/* Detailed source-code truncated for AI context efficiency. */
```

### 底部按钮栏

#### 隐藏默认提交按钮

Form 默认会在底部渲染一个提交按钮，用于执行表单的提交行为。你可以通过两种方式去掉这个默认的提交按钮：

1. 配置：`"submitText": ""`
2. 配置：`"actions": []`

```schema: scope="body"
[
    {
      "type": "form",
      "title": "通过 submitText 去掉提交按钮",
      "submitText": "",
      "body": [
        {
          "type": "input-text",
          "name": "email",
          "label": "邮箱"
        }
      ]
    },
    {
      "type": "form",
      "title": "通过 actions 去掉提交按钮",
      "actions": [],
      "body": [
        {
          "type": "input-text",
          "name": "email",
          "label": "邮箱"
        }
      ]
    }
  ]
```

#### 配置若干自定义按钮

同样，你可以通过 actions 属性，配置任意你想要的行为按钮。

```schema: scope="body"
{
    "type": "form",
    "title": "表单",
    "body": [
      {
        "type": "input-text",
        "name": "email",
        "label": "邮箱"
      },
      {
        "type": "input-password",
        "name": "password",
        "label": "密码"
      }
    ],
    "actions": [
      {
        "type": "submit",
        "label": "登录"
      },
      {
        "type": "action",
        "actionType": "dialog",
        "label": "登录须知",
        "dialog": {
          "title": "登录须知",
          "body": "登录须知"
        }
      },
      {
        "type": "button",
        "label": "百度一下",
        "url": "https://www.baidu.com/"
      }
    ]
  }
```

请记住，如果想触发表单提交行为，请配置`"actionType": "submit"`或`"type": "submit"`按钮

### 去掉表单边框

通过配置`"wrapWithPanel": false`，可以去掉默认表单边框（包括标题，按钮栏以及边距样式等）。

```schema: scope="body"
{
    "type": "form",
    "wrapWithPanel": false,
    "body": [
      {
        "type": "input-text",
        "name": "email",
        "label": "邮箱"
      },
      {
        "type": "input-password",
        "name": "password",
        "label": "密码"
      }
    ]
  }
```

**注意！配置该属性后，`title`和`actions`属性将失效并无法渲染，请在表单内自行配置。**

### 固定底部栏

如果表单项较多导致表单过长，而不方便操作底部的按钮栏，可以配置`"affixFooter": true`属性，将底部按钮栏固定在浏览器底部

## 表单静态展示

> 2.4.0 及以上版本

在一些场景，表单提交后需要将填写的内容静态展示

### 设置初始状态

通过配置`static: true`将整个表单设置为静态展示，单个表单项也支持此配置

```schema: scope="body"
{
  "type": "form",
  "title": "表单状态切换",
  "mode": "horizontal",
  "labelWidth": 150,
  "id": "allFormStatic",
  "static": true,
  "body": [
    {
      "type": "input-text",
      "name": "var1",
      "label": "输入框",
      "value": "text"
    },
    {
      "type": "input-color",
      "name": "var2",
      "label": "颜色选择",
      "value": "#F0F"
    },
    {
      "type": "switch",
      "name": "switch",
      "label": "开关",
      "option": "开关说明",
      "value": true
    }
  ],
  "actions": []
}
```

### 切换输入态和展示态

也支持使用[动作](#动作表)切换表单的 输入态和展示态（静态），也可以使用动作对单个表单项进行状态切换  
可以在[示例页](../../../examples/form/switchDisplay)查看表单项的静态展示方式

```schema: scope="body"
{
  "type": "form",
  "title": "表单状态切换",
  "mode": "horizontal",
  "labelWidth": 150,
  "id": "allFormSwitch",
  "data": {
    "isStatic": false
  },
  "body": [
    {
      "type": "input-text",
      "name": "var1",
      "label": "输入框",
      "value": "text"
    },
    {
      "type": "input-color",
      "name": "var2",
      "label": "颜色选择",
      "value": "#F0F"
    },
    {
      "type": "switch",
      "name": "switch",
      "label": "开关",
      "option": "开关说明",
      "value": true
    },
    {
      "type": "button-toolbar",
      "buttons": [
        {
          "type": "button",
          "label": "${isStatic ? '编辑' : '提交'}",
          "level": "primary",
          "onEvent": {
            "click": {
              "actions": [
                {
                  "actionType": "setValue",
                  "componentId": "allFormSwitch",
                  "args": {
                    "value": {
                      "isStatic": "${!isStatic}"
                    }
                  }
                },
                {
                  "actionType": "static",
                  "componentId": "allFormSwitch",
                  "expression": "${!isStatic}"
                },
                {
                  "actionType": "nonstatic",
                  "componentId": "allFormSwitch",
                  "expression": "${isStatic}"
                }
              ]
            }
          }
        }
      ]
    }
  ],
  "actions": []
}
```

## 表单项数据初始化

表单可以通过配置`initApi`，实现表单初始化时请求接口，用于展示数据或初始化表单项。

```schema: scope="body"
{
    "type": "form",
    "initApi": "/api/mock2/form/initData",
    "title": "编辑用户信息",
    "body": [
      {
        "type": "input-text",
        "name": "name",
        "label": "姓名"
      },
      {
        "type": "input-text",
        "name": "email",
        "label": "邮箱"
      }
    ]
}
```

比如以上这个例子接口返回为

```
{
    status: 0,
    msg: "",
    data: {
        name: "Amis Renderer",
        author: "fex",
        date: 1615978757,
        info: ""
    }
}
```

第一个表单项的 name 配置为 `name`，所以这个表单初始化完毕后展示 `Amis Renderer`。

> 表单项的 value 是不支持表达式，所以不要尝试用 `value: "${xxx}"` 来关联数据。

### 轮询初始化请求

Form 支持轮询初始化接口，步骤如下：

1. 配置`initApi`
2. 配置 `interval`：单位为毫秒，最小 `1000`

```schema: scope="body"
{
    "type": "form",
    "initApi": "/api/mock2/page/initData",
    "interval": 3000,
    "title": "表单",
    "body": [
      {
        "type": "input-text",
        "name": "date",
        "label": "时间戳"
      }
    ]
  }
```

如果希望在满足某个条件的情况下停止轮询，配置`stopAutoRefreshWhen`表达式。

```schema: scope="body"
{
    "type": "form",
    "initApi": "/api/mock2/page/initData",
    "interval": 3000,
    "title": "表单",
    "stopAutoRefreshWhen": "this.date % 5",
    "body": [
      {
        "type": "input-text",
        "name": "date",
        "label": "时间戳"
      }
    ]
  }
```

### 静态初始化数据域

我们也可以手动设置 form 的数据域来初始化多个表单项值

```schema: scope="body"
{
    "type": "form",
    "data": {
      "name": "rick",
      "email": "rick@gmail.com"
    },
    "title": "用户信息",
    "body": [
      {
        "type": "input-text",
        "name": "name",
        "label": "姓名"
      },
      {
        "type": "input-email",
        "name": "email",
        "label": "邮箱"
      }
    ]
  }
```

注意这里的 `data` 会进行数据映射，如果想不映射，需要进行转义，比如下面的例子

```schema: scope="body"
{
    "type": "form",
    "data": {
      "name": "\\${rick}",
      "email": "rick@gmail.com"
    },
    "title": "用户信息",
    "body": [
      {
        "type": "input-text",
        "name": "name",
        "label": "姓名"
      },
      {
        "type": "input-email",
        "name": "email",
        "label": "邮箱"
      }
    ]
  }
```

### 数据格式一致性问题

当表单来初始化表单项值时，需要保持数据格式的一致性。

如果表单初始化的值与表单项配置的数据格式不符合，而且用户没有再次操作该表单项，而直接提交表单，那么会将当前默认值原封不动的提交给后端，也许会导致不一致性的问题，我们看一个例子：

```schema: scope="body"
{
    "type": "form",
    "data": {
        "select": ["a", "c"]
    },
    "body": [
        {
            "label": "选项",
            "type": "select",
            "name": "select",
            "multiple": true,
            "options": [
                {
                    "label":"A",
                    "value":"a"
                },
                {
                    "label":"B",
                    "value":"b"
                },
                {
                    "label":"C",
                    "value":"c"
                }
            ]
        }
    ]
}
```

上例中， `select` 我们配置了`"multiple": true`，预期中，我们希望选中 `A` 和 `C` 项时，表单项的数据格式为：`"a,c"`，但是我们表单数据域中，`select`默认值为`"value": ["a", "c"]`，并不符合我们当前表单项的数据格式配置，这样会导致两个问题：

1. 有可能不会默认选中 `A` 和 `C` 选项；
2. 当不操作该表单项，直接提交时，预期是：`"a,c"`，但提交给后端的数据为：`["a", "c"]`，导致了不一致性的问题。

> 通过 `initApi` 配置默认值同理，不再赘述

因此一定确保默认值与选择器表单项数据格式配置相匹配。

## 表单提交

配置`api`属性，当表单执行提交行为时，会默认将当前表单数据域中的数据使用`post`方式发送给所配置`api`

```schema: scope="body"
{
    "type": "form",
    "api": "/api/saveForm",
    "title": "用户信息",
    "body": [
      {
        "type": "input-text",
        "name": "name",
        "label": "姓名"
      },
      {
        "type": "input-email",
        "name": "email",
        "label": "邮箱"
      }
    ]
  }
```

点击提交按钮，会看到发送表单请求，请求数据体为：

```json
{
  "name": "xxx",
  "email": "xxx@xx.com"
}
```

发送请求默认为 `POST` 方式，会将所有表单项整理成一个对象发送过去。除此之外你可以主动获取以下信息。

- `diff` 只会包含 `diff` 结果
- `prinstine` 原始数据
  如:

```json
{
  "api": {
    "method": "post",
    "url": "/api/xxx/save",
    "data": {
      "modified": "$$",
      "diff": "${diff}",
      "origin": "${prinstine}"
    }
  }
}
```

> 如果 返回了 `data` 对象，且是对象，会把结果 merge 到表单数据里面。

当你需要配置特定的请求方式，请求体，`header`时，使用对象类型 api 配置，并使用 数据映射 进行数据配置。

下面示例我们更改了请求方法为`PUT`，并在原提交数据的基础上添加一个字段`"_from"`。更多用法查看 [API 文档](../../../docs/types/api) 和 [数据映射](../../../docs/concepts/data-mapping)文档

```schema: scope="body"
{
    "type": "form",
    "initApi": {
      "method": "put",
      "url": "/api/mock2/page/initData",
      "data": {
        "&": "$$$$",
        "_from": "browser"
      }
    },
    "title": "用户信息",
    "body": [
      {
        "type": "input-text",
        "name": "name",
        "label": "姓名"
      },
      {
        "type": "input-email",
        "name": "email",
        "label": "邮箱"
      }
    ]
  }
```

触发表单提交行为有下面几种方式：

1. 默认的`提交按钮`
2. 为行为按钮配置`"actionType": "submit"`
3. 配置`"type": "submit"`的按钮

### 轮询提交请求

通过设置`asyncApi`，当表单提交发送保存接口后，还会继续轮询请求该接口，默认间隔为`3秒`，直到返回 `finished` 属性为 `true` 才结束。

```schema: scope="body"
{
    "type": "form",
    "api": "/api/mock2/form/saveForm",
    "asyncApi": "/api/mock2/page/initData",
    "title": "用户信息",
    "body": [
      {
        "type": "input-text",
        "name": "name",
        "label": "姓名"
      },
      {
        "type": "input-email",
        "name": "email",
        "label": "邮箱"
      }
    ]
  }
```

如果决定结束轮询的标识字段名不是 `finished`，请设置`finishedField`属性，比如：`"finishedField": "is_success"`

## 表单校验

一般可以通过在[表单项格式校验](./formitem#%E6%A0%BC%E5%BC%8F%E6%A0%A1%E9%AA%8C)中，配置校验规则完成校验，但是有时候，我们需要组合多个表单项实现一些校验，这时可以通过配置 `rules` 来实现组合校验。

例如下例，我们想校验 `a` 和 `b` 表单项不可以同时有值，否则就报错，则可以进行如下配置：

```schema:scope="body"
{
  "type": "form",
  "api": "/api/form/saveForm",
  "rules": [
    {
      "rule": "!(data.a && data.b)",
      "message": "a 和 b 不能同时有值"
    }
  ],
  "body": [
    {
      "type": "input-text",
      "name": "a",
      "label": "A"
    },
    {
      "type": "input-text",
      "name": "b",
      "label": "B"
    }
  ]
}
```

> `rule` 编写使用 [表达式](../../../docs/concepts/expression)

### 组合校验高亮表单项

> 1.6.5 及以上版本

默认组合校验的错误信息显示在表单的底部，如果希望可以定位到表单项自己，则可以通过配置 `name` 来高亮错误。

```schema:scope="body"
{
  "type": "form",
  "api": "/api/form/saveForm",
  "rules": [
    {
      "rule": "!(data.a && data.b)",
      "message": "a 和 b 不能同时有值",
      "name": ["a", "b"]
    }
  ],
  "body": [
    {
      "type": "input-text",
      "name": "a",
      "label": "A"
    },
    {
      "type": "input-text",
      "name": "b",
      "label": "B"
    }
  ]
}
```

## 重置表单

配置`"type": "reset"`或者`"actionType": "reset"`的按钮，可以实现点击重置表单项值。

```schema: scope="body"
{
    "type": "form",
    "body": [
      {
        "type": "input-text",
        "name": "name",
        "label": "姓名"
      },
      {
        "type": "input-email",
        "name": "email",
        "label": "邮箱"
      }
    ],
    "actions": [
        {
            "type": "reset",
            "label": "重置"
        },
        {
            "type": "submit",
            "label": "保存"
        }
    ]
  }
```

> **请注意：**这里的重置是将表单数据域重置到**初始状态**，**而不是清空**，如果你配置了初始化接口，那么重置操作是会**将表单项重置至初始化表单项值**

## 表单数据域调试

配置`debug:true`可以查看当前表单的数据域数据详情，方便数据映射、表达式等功能调试，如下，你可以修改表单项查看数据域变化。`debugConfig`可以额外配置 debug 区域的相关配置，具体配置请参考[Json 组件属性](../json.md#属性表)。

> 2.2.0 及以上版本支持`debugConfig`

```schema: scope="body"
{
    "type": "form",
    "title": "用户信息",
    "debug": true,
    "debugConfig": {
      "enableClipboard": true,
      "displayDataTypes": true
    },
    "body": [
      {
        "type": "input-text",
        "name": "name",
        "label": "姓名"
      },
      {
        "type": "input-email",
        "name": "email",
        "label": "邮箱"
      }
    ]
  }
```

> 该配置不会展示完整的数据链，只会展示当前表单的数据域

## 禁用数据链

默认表单是可以获取到完整数据链中的数据的，但是该默认行为不适用于所有场景，例如：

在 CRUD 的列表项中配置弹框，弹框中有一个表单，则该表单项中所有的同`name`表单项都会根据上层`crud`的行数据进行初始化，如果你是实现编辑的功能那并没有是什么问题，但是如果你是新建功能，那么这将不符合你的预期，你可以手动设置`"canAccessSuperData": false`来关闭该行为

## 提交后行为

表单提交成功后，可以执行一些行为。

### 重置表单

如果想提交表单成功后，重置当前表单至初始状态，可以配置`"resetAfterSubmit": true`。

```schema: scope="body"
{
    "type": "form",
    "api": "/api/mock2/form/saveForm",
    "resetAfterSubmit": true,
    "body": [
      {
        "type": "input-text",
        "name": "name",
        "label": "姓名："
      },
      {
        "name": "email",
        "type": "input-email",
        "label": "邮箱："
      }
    ]
  }
```

编辑表单项，点击提交，成功后会发现表单项的值会重置到初始状态，即空

> 注意，如果表单项有默认值，则会将该表单项的值重置至该默认值。

### 跳转页面

配置`redirect`属性，可以指定表单提交成功后要跳转至的页面

```schema: scope="body"
{
    "type": "form",
    "initApi": "/api/mock2/page/initData",
    "redirect": "/user/list",
    "title": "用户信息",
    "body": [
      {
        "type": "input-text",
        "name": "name",
        "label": "姓名"
      },
      {
        "type": "input-email",
        "name": "email",
        "label": "邮箱"
      }
    ]
  }
```

### 刷新目标组件

配置`reload`属性为其他组件`name`值，可以在表单提交成功之后，刷新指定组件。

```schema: scope="body"
[
    {
      "type": "form",
      "initApi": "/api/mock2/page/initData",
      "title": "用户信息",
      "reload": "my_service",
      "body": [
        {
          "type": "input-text",
          "name": "name",
          "label": "姓名"
        },
        {
          "type": "input-email",
          "name": "email",
          "label": "邮箱"
        }
      ]
    },
    {
      "type": "service",
      "name": "my_service",
      "api": "/api/mock2/page/initData",
      "body": "service初识数据"
    }
  ]
```

上例中`form`提交成功后，会触发`name`为`my_service`的`Service`组件重新请求初始化接口

上面示例是一种[组件间联动](../../docs/concepts/linkage#%E7%BB%84%E4%BB%B6%E9%97%B4%E8%81%94%E5%8A%A8)

### 显示提交的返回结果

默认情况下表单提交返回结果会写入当前表单的数据域，如果要显示在当前表单，可以直接使用 `static` 类型，比如下面的例子

```schema: scope="body"
{
  "type": "form",
  "api": "/api/mock2/form/saveForm",
  "title": "用户信息",
  "body": [
    {
      "type": "input-text",
      "name": "name",
      "label": "姓名"
    },
    {
      "type": "static",
      "name": "id",
      "visibleOn": "typeof data.id !== 'undefined'",
      "label": "返回 ID"
    }
  ]
}
```

### 将提交返回内容发送到其它组件

还可以将返回结果发送到其它组件，首先设置另一个表单的 `name`，然后通过 `reload` 配置参数来提交

```schema: scope="body"
[
  {
    "type": "form",
    "api": "/api/mock2/form/saveForm",
    "title": "用户信息",
    "reload": "otherForm?id=${id}",
    "body": [
      {
        "type": "input-text",
        "name": "name",
        "label": "姓名"
      }
    ]
  },
  {
    "type": "form",
    "name": "otherForm",
    "title": "返回结果",
    "actions": [],
    "body": [
      {
        "type": "static",
        "name": "id",
        "label": "返回 ID"
      }
    ]
  }
]
```

### 将数据域发送给目标组件

配置`target`属性为目标组件`name`值，可以在触发提交行为后，将当前表单的数据域发送给目标组件。

```schema: scope="body"
[
    {
      "type": "form",
      "target": "detailForm",
      "body": [
        {
          "type": "input-text",
          "placeholder": "关键字",
          "name": "keywords"
        }
      ]
    },
    {
      "type": "form",
      "name": "detailForm",
      "initApi": "/api/mock2/page/initData?keywords=${keywords}",
      "body": [
        {
          "label": "名称",
          "type": "static",
          "name": "name"
        },
        {
          "label": "作者",
          "type": "static",
          "name": "author"
        },
        {
          "label": "关键字",
          "type": "static",
          "name": "keywords"
        },
        {
          "label": "请求时间",
          "type": "static-datetime",
          "format": "YYYY-MM-DD HH:mm:ss",
          "name": "date"
        }
      ]
    }
  ]
```

第一个表单在提交时，会将它的表单数据域数据发送给`detailForm`表单，触发`detailForm`的初始化接口联动，重新请求接口更新数据域，并更新关键字表单项。

上面示例组合使用了 [组件间联动](../../docs/concepts/linkage#%E7%BB%84%E4%BB%B6%E9%97%B4%E8%81%94%E5%8A%A8) 和 [接口联动](../../docs/concepts/linkage#%E6%8E%A5%E5%8F%A3%E8%81%94%E5%8A%A8)

## 持久化保存表单项数据

表单默认在重置之后（切换页面、弹框中表单关闭表单），会自动清空掉表单中的所有数据，如果你想持久化保留当前表单项的数据而不清空它，那么通过 Form 配置 `persistData: "xxx"`，指定一个 `key` ，来实现数据持久化保存

> 注意，如果使用在 CRUD 列表中的编辑框内的 Form 中，可以利用数据映射语法，`persistData: "xxx:${id}"`，来为 form 指定一个唯一的 key

如果想提交成功后，清空该缓存，则配置`"clearPersistDataAfterSubmit": true`

### 限制只存储某些 key

> 2.3.0 及以上版本

如果只想存储部分 key，可以配置 `"persistDataKeys": ["key1", "key2"]`，这样就只有 name 为 key1 和 key2 的表单项数据会持久化

## 禁用回车提交

表单默认情况下回车就会提交，如果想阻止这个行为，可以加上 `preventEnterSubmit` 配置项。

```schema: scope="body"
{
    "type": "form",
    "api": "/api/mock2/form/saveForm",
    "preventEnterSubmit": true,
    "body": [
      {
        "type": "input-text",
        "name": "name",
        "label": "姓名："
      },
      {
        "name": "email",
        "type": "input-email",
        "label": "邮箱："
      }
    ]
}
```

## 属性表

| 属性名                      | 类型                                                                      | 默认值                                     | 说明                                                                                                                                                                                                                                                                                                                                                         |
| --------------------------- | ------------------------------------------------------------------------- | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| type                        | `string`                                                                  |                                            | `"form"` 指定为 Form 渲染器                                                                                                                                                                                                                                                                                                                                  |
| name                        | `string`                                                                  |                                            | 设置一个名字后，方便其他组件与其通信                                                                                                                                                                                                                                                                                                                         |
| mode                        | `string`                                                                  | `normal`                                   | 表单展示方式，可以是：`normal`、`horizontal` 或者 `inline`                                                                                                                                                                                                                                                                                                   |
| horizontal                  | `Object`                                                                  | `{"left":2, "right":10, "justify": false}` | 当 mode 为 `horizontal` 时有用，用来控制 label 的展示占比                                                                                                                                                                                                                                                                                                    |
| labelAlign                  | `"right" \| "left"`                                                       | `"right"`                                  | 表单项标签对齐方式，默认右对齐，仅在 `mode`为`horizontal` 时生效                                                                                                                                                                                                                                                                                             |
| labelWidth                  | `number \| string`                                                        |                                            | 表单项标签自定义宽度                                                                                                                                                                                                                                                                                                                                         |
| title                       | `string`                                                                  | `"表单"`                                   | Form 的标题                                                                                                                                                                                                                                                                                                                                                  |
| submitText                  | `String`                                                                  | `"提交"`                                   | 默认的提交按钮名称，如果设置成空，则可以把默认按钮去掉。                                                                                                                                                                                                                                                                                                     |
| className                   | `string`                                                                  |                                            | 外层 Dom 的类名                                                                                                                                                                                                                                                                                                                                              |
| body                        | Array<[表单项](./formitem) or [SchemaNode](../../docs/types/schemanode) > |                                            | Form 表单项集合                                                                                                                                                                                                                                                                                                                                              |
| actions                     | Array<[行为按钮](../action)>                                              |                                            | Form 提交按钮，成员为 Action                                                                                                                                                                                                                                                                                                                                 |
| messages                    | `Object`                                                                  |                                            | 消息提示覆写，默认消息读取的是 API 返回的消息，但是在此可以覆写它。                                                                                                                                                                                                                                                                                          |
| messages.fetchSuccess       | `string`                                                                  |                                            | 获取成功时提示                                                                                                                                                                                                                                                                                                                                               |
| messages.fetchFailed        | `string`                                                                  |                                            | 获取失败时提示                                                                                                                                                                                                                                                                                                                                               |
| messages.saveSuccess        | `string`                                                                  |                                            | 保存成功时提示                                                                                                                                                                                                                                                                                                                                               |
| messages.saveFailed         | `string`                                                                  |                                            | 保存失败时提示                                                                                                                                                                                                                                                                                                                                               |
| messages.validateFailed     | `string`                                                                  | `"依赖的部分字段没有通过验证"`             | 表单验证失败时的提示                                                                                                                                                                                                                                                                                                                                         |
| wrapWithPanel               | `boolean`                                                                 | `true`                                     | 是否让 Form 用 panel 包起来，设置为 false 后，actions 将无效。                                                                                                                                                                                                                                                                                               |
| panelClassName              | `string`                                                                  |                                            | 外层 panel 的类名                                                                                                                                                                                                                                                                                                                                            |
| api                         | [API](../../../docs/types/api)                                            |                                            | Form 用来保存数据的 api。                                                                                                                                                                                                                                                                                                                                    |
| initApi                     | [API](../../../docs/types/api)                                            |                                            | Form 用来获取初始数据的 api。                                                                                                                                                                                                                                                                                                                                |
| rules                       | Array<{rule:string;message:string;name?: string[]}>                       |                                            | 表单组合校验规则                                                                                                                                                                                                                                                                                                                                             |
| interval                    | `number`                                                                  | `3000`                                     | 刷新时间(最低 3000)                                                                                                                                                                                                                                                                                                                                          |
| silentPolling               | `boolean`                                                                 | `false`                                    | 配置刷新时是否显示加载动画                                                                                                                                                                                                                                                                                                                                   |
| stopAutoRefreshWhen         | `string`                                                                  | `""`                                       | 通过[表达式](./Types.md#表达式) 来配置停止刷新的条件                                                                                                                                                                                                                                                                                                         |
| initAsyncApi                | [API](../../../docs/types/api)                                            |                                            | Form 用来获取初始数据的 api,与 initApi 不同的是，会一直轮询请求该接口，直到返回 finished 属性为 true 才结束。                                                                                                                                                                                                                                                |
| initFetch                   | `boolean`                                                                 | `true`                                     | 设置了 initApi 或者 initAsyncApi 后，默认会开始就发请求，设置为 false 后就不会一开始就请求接口                                                                                                                                                                                                                                                               |
| initFetchOn                 | `string`                                                                  |                                            | 用表达式来配置                                                                                                                                                                                                                                                                                                                                               |
| initFinishedField           | `string`                                                                  | `finished`                                 | 设置了 initAsyncApi 后，默认会从返回数据的 data.finished 来判断是否完成，也可以设置成其他的 xxx，就会从 data.xxx 中获取                                                                                                                                                                                                                                      |
| initCheckInterval           | `number`                                                                  | `3000`                                     | 设置了 initAsyncApi 以后，默认拉取的时间间隔                                                                                                                                                                                                                                                                                                                 |
| asyncApi                    | [API](../../../docs/types/api)                                            |                                            | 设置此属性后，表单提交发送保存接口后，还会继续轮询请求该接口，直到返回 `finished` 属性为 `true` 才结束。                                                                                                                                                                                                                                                     |
| checkInterval               | `number`                                                                  | 3000                                       | 轮询请求的时间间隔，默认为 3 秒。设置 `asyncApi` 才有效                                                                                                                                                                                                                                                                                                      |
| finishedField               | `string`                                                                  | `"finished"`                               | 如果决定结束的字段名不是 `finished` 请设置此属性，比如 `is_success`                                                                                                                                                                                                                                                                                          |
| submitOnChange              | `boolean`                                                                 | `false`                                    | 表单修改即提交                                                                                                                                                                                                                                                                                                                                               |
| submitOnInit                | `boolean`                                                                 | `false`                                    | 初始就提交一次                                                                                                                                                                                                                                                                                                                                               |
| resetAfterSubmit            | `boolean`                                                                 | `false`                                    | 提交后是否重置表单                                                                                                                                                                                                                                                                                                                                           |
| primaryField                | `string`                                                                  | `"id"`                                     | 设置主键 id, 当设置后，检测表单是否完成时（asyncApi），只会携带此数据。                                                                                                                                                                                                                                                                                      |
| target                      | `string`                                                                  |                                            | 默认表单提交自己会通过发送 api 保存数据，但是也可以设定另外一个 form 的 name 值，或者另外一个 `CRUD` 模型的 name 值。 如果 target 目标是一个 `Form` ，则目标 `Form` 会重新触发 `initApi`，api 可以拿到当前 form 数据。如果目标是一个 `CRUD` 模型，则目标模型会重新触发搜索，参数为当前 Form 数据。当目标是 `window` 时，会把当前表单的数据附带到页面地址上。 |
| redirect                    | `string`                                                                  |                                            | 设置此属性后，Form 保存成功后，自动跳转到指定页面。支持相对地址，和绝对地址（相对于组内的）。                                                                                                                                                                                                                                                                |
| reload                      | `string`                                                                  |                                            | 操作完后刷新目标对象。请填写目标组件设置的 name 值，如果填写为 `window` 则让当前页面整体刷新。                                                                                                                                                                                                                                                               |
| autoFocus                   | `boolean`                                                                 | `false`                                    | 是否自动聚焦。                                                                                                                                                                                                                                                                                                                                               |
| canAccessSuperData          | `boolean`                                                                 | `true`                                     | 指定是否可以自动获取上层的数据并映射到表单项上                                                                                                                                                                                                                                                                                                               |
| persistData                 | `string`                                                                  | `""`                                       | 指定一个唯一的 key，来配置当前表单是否开启本地缓存                                                                                                                                                                                                                                                                                                           |
| persistDataKeys             | `string[]`                                                                | `""`                                       | 指指定只有哪些 key 缓存                                                                                                                                                                                                                                                                                                                                      |
| clearPersistDataAfterSubmit | `boolean`                                                                 | `true`                                     | 指定表单提交成功后是否清除本地缓存                                                                                                                                                                                                                                                                                                                           |
| preventEnterSubmit          | `boolean`                                                                 | `false`                                    | 禁用回车提交表单                                                                                                                                                                                                                                                                                                                                             |
| trimValues                  | `boolean`                                                                 | `false`                                    | trim 当前表单项的每一个值                                                                                                                                                                                                                                                                                                                                    |
| promptPageLeave             | `boolean`                                                                 | `false`                                    | form 还没保存，即将离开页面前是否弹框确认。                                                                                                                                                                                                                                                                                                                  |
| columnCount                 | `number`                                                                  | 0                                          | 表单项显示为几列                                                                                                                                                                                                                                                                                                                                             |
| inheritData                 | `boolean`                                                                 | `true`                                     | 默认表单是采用数据链的形式创建个自己的数据域，表单提交的时候只会发送自己这个数据域的数据，如果希望共用上层数据域可以设置这个属性为 false，这样上层数据域的数据不需要在表单中用隐藏域或者显式映射才能发送了。                                                                                                                                                 |
| static                      | `boolean`                                                                 |                                            | `2.4.0` 整个表单静态方式展示，详情请查看[示例页](../../../examples/form/switchDisplay)                                                                                                                                                                                                                                                                       |
| staticClassName             | `string`                                                                  |                                            | `2.4.0` 表单静态展示时使用的类名                                                                                                                                                                                                                                                                                                                             |
| closeDialogOnSubmit         | `boolean`                                                                 |                                            | 提交的时候是否关闭弹窗。当 form 里面有且只有一个弹窗的时候，本身提交会触发弹窗关闭，此属性可以关闭此行为                                                                                                                                                                                                                                                     |

## 事件表

当前组件会对外派发以下事件，可以通过`onEvent`来监听这些事件，并通过`actions`来配置执行的动作，在`actions`中可以通过`${事件参数名}`或`${event.data.[事件参数名]}`来获取事件产生的数据，详细请查看[事件动作](../../docs/concepts/event-action)。

| 事件名称              | 事件参数                                                                                                                                                                                     | 说明                                                                                                                                        |
| --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| 事件名称              | 事件参数                                                                                                                                                                                     | 说明                                                                                                                                        |
| inited                | `responseData: any` 请求的响应数据<br />`responseStatus: number` 响应状态，0 表示成功<br />`responseMsg: string`响应消息, `error`表示接口是否成功<br/>`[name]: any` 当前数据域中指定字段的值 | 表单初始化完成事件，不管配置不配置 initApi 都会触发，实际上还会等部分子表单项初始化完成                                                     |
| change                | `event.data: object` 当前表单数据                                                                                                                                                            | 表单值变化时触发                                                                                                                            |
| formItemValidateSucc  | `event.data: object` 当前表单数据<br />`event.data.__formName` 表单项名字<br />`event.data.__formValue` 表单项值                                                                             | 表单项校验成功时触发                                                                                                                        |
| formItemValidateError | `event.data: object` 当前表单数据 <br />`event.data.__formName` 表单项名字<br />`event.data.__formValue` 表单项值<br />`event.data.__errors`表单项错误                                       | 表单项校验失败时触发                                                                                                                        |
| validateSucc          | `event.data: object` 当前表单数据                                                                                                                                                            | 表单校验成功时触发                                                                                                                          |
| validateError         | `event.data: object` 当前表单数据                                                                                                                                                            | 表单校验失败时触发                                                                                                                          |
| submit                | `event.data: object` 当前表单数据                                                                                                                                                            | 点击提交按钮或者触发表单提交动作的时候触发（配置了该事件后将不会触发表单提交时的校验、提交到 api 或者 target 等行为，所有行为需要自己配置） |
| submitSucc            | `event.data.result: object` api 远程请求成功后返回的结果数据                                                                                                                                 | 提交成功时触发                                                                                                                              |
| submitFail            | `event.data.error: object` api 远程请求失败后返回的错误信息                                                                                                                                  | 提交失败时触发                                                                                                                              |
| initApiFinished       | `[name]: any` 当前数据域中指定字段的值 <br />`event.data.__trigger` 触发原因：`init` \| `reload`                                                                                             | asyncApi 远程请求轮训结束                                                                                                                   |
| asyncApiFinished      | `[name]: any` 当前数据域中指定字段的值                                                                                                                                                       | asyncApi 远程请求轮训结束                                                                                                                   |

### inited

```schema: scope="body"
[
  {
    "type": "form",
    "initApi": "/api/mock2/form/initData",
    "title": "初始化表单",
    "body": [
      {
        "type": "input-text",
        "name": "name",
        "label": "姓名"
      },
      {
        "type": "input-text",
        "name": "email",
        "label": "邮箱"
      }
    ],
    "actions": [],
    "onEvent": {
      "inited": {
        "actions": [
          {
            "actionType": "setValue",
            "componentId": "init_text",
            "args": {
              "value": "responseData: ${event.data.responseData|json},responseStatus: ${event.data.responseStatus},responseMsg: ${event.data.responseMsg}"
            }
          }
        ]
      }
    }
  },
  {
    "type": "input-text",
    "id": "init_text",
    "static": true,
    "name": "tip",
    "label": "上下文"
  }
]
```

### change

```schema: scope="body"
[
  {
    "type": "form",
    "title": "尝试修改表单项",
    "body": [
      {
        "type": "input-text",
        "name": "name",
        "label": "姓名"
      },
      {
        "type": "input-text",
        "name": "email",
        "label": "邮箱"
      }
    ],
    "actions": [],
    "onEvent": {
      "change": {
        "actions": [
          {
            "actionType": "setValue",
            "componentId": "change_text",
            "args": {
              "value": "${event.data|json}"
            }
          }
        ]
      }
    }
  },
  {
    "type": "input-text",
    "id": "change_text",
    "static": true,
    "name": "tip",
    "label": "上下文"
  }
]
```

### formItemValidateSucc

事件上下文

- `event.data` 表单的全部数据
- `event.data.__formName` 表单项名字
- `event.data.__formValue` 表单项值

```schema: scope="body"
[
  {
    "type": "form",
    "title": "尝试修改表单项",
    "api": "/api/mock2/form/saveForm",
    "body": [
      {
        "type": "input-text",
        "name": "name",
        "label": "姓名",
        "validateOnChange": true,
        "value": "amis"
      },
      {
        "type": "input-text",
        "name": "email",
        "label": "邮箱",
        "value": "amis@baidu.com",
        "validateOnChange": true,
        "required": true,
        "validations": {
          "isEmail": true
        }
      }
    ],
    "onEvent": {
      "formItemValidateSucc": {
        "actions": [
          {
            "actionType": "setValue",
            "componentId": "formitem_validate_succ_text",
            "args": {
              "value": "${event.data|json}"
            }
          }
        ]
      },
      "formItemValidateError": {
        "actions": [
          {
            "actionType": "setValue",
            "componentId": "formitem_validate_succ_text",
            "args": {
              "value": "failed"
            }
          }
        ]
      }
    }
  },
  {
    "type": "input-text",
    "id": "formitem_validate_succ_text",
    "static": true,
    "name": "tip",
    "label": "上下文"
  }
]
```

### formItemValidateError

事件上下文

- `event.data` 表单的全部数据
- `event.data.__formName` 表单项名字
- `event.data.__formValue` 表单项值
- `event.data.__errors` 表单项的错误，字符数组

示例请参考 `formItemValidateSucc` 的例子

### validateSucc

```schema: scope="body"
[
  {
    "type": "form",
    "title": "尝试修改表单项",
    "api": "/api/mock2/form/saveForm",
    "body": [
      {
        "type": "input-text",
        "name": "name",
        "label": "姓名",
        "value": "amis"
      },
      {
        "type": "input-text",
        "name": "email",
        "label": "邮箱",
        "value": "amis@baidu.com",
        "required": true,
        "validations": {
          "isEmail": true
        }
      }
    ],
    "onEvent": {
      "validateSucc": {
        "actions": [
          {
            "actionType": "setValue",
            "componentId": "validate_succ_text",
            "args": {
              "value": "${event.data|json}"
            }
          }
        ]
      }
    }
  },
  {
    "type": "input-text",
    "id": "validate_succ_text",
    "static": true,
    "name": "tip",
    "label": "上下文"
  }
]
```

### validateError

```schema: scope="body"
[
  {
    "type": "form",
    "title": "尝试修改表单项",
    "api": "/api/mock2/form/x",
    "body": [
      {
        "type": "input-text",
        "name": "name",
        "label": "姓名",
        "value": "amis"
      },
      {
        "type": "input-text",
        "name": "email",
        "label": "邮箱",
        "value": "amis",
        "required": true,
        "validations": {
          "isEmail": true
        }
      }
    ],
    "onEvent": {
      "validateError": {
        "actions": [
          {
            "actionType": "setValue",
            "componentId": "validate_fail_text",
            "args": {
              "value": "${event.data|json}"
            }
          }
        ]
      }
    }
  },
  {
    "type": "input-text",
    "id": "validate_fail_text",
    "static": true,
    "name": "tip",
    "label": "上下文"
  }
]
```

### submit

```schema: scope="body"
[
  {
    "type": "form",
    "title": "尝试提交表单",
    "body": [
      {
        "type": "input-text",
        "name": "name",
        "label": "姓名",
        "value": "amis"
      },
      {
        "type": "input-text",
        "name": "email",
        "label": "邮箱",
        "value": "amis@baidu.com"
      }
    ],
    "onEvent": {
      "submit": {
        "actions": [
          {
            "actionType": "setValue",
            "componentId": "submit_text",
            "args": {
              "value": "${event.data|json}"
            }
          }
        ]
      }
    }
  },
  {
    "type": "input-text",
    "id": "submit_text",
    "static": true,
    "name": "tip",
    "label": "上下文"
  }
]
```

### submitSucc

```schema: scope="body"
[
  {
    "type": "form",
    "title": "尝试提交表单",
    "api": "/api/mock2/form/saveForm",
    "body": [
      {
        "type": "input-text",
        "name": "name",
        "label": "姓名",
        "value": "amis"
      },
      {
        "type": "input-text",
        "name": "email",
        "label": "邮箱",
        "value": "amis@baidu.com"
      }
    ],
    "onEvent": {
      "submitSucc": {
        "actions": [
          {
            "actionType": "setValue",
            "componentId": "submit_succ_text",
            "args": {
              "value": "${event.data.result|json}"
            }
          }
        ]
      }
    }
  },
  {
    "type": "input-text",
    "id": "submit_succ_text",
    "static": true,
    "name": "tip",
    "label": "上下文"
  }
]
```

### submitFail

```schema: scope="body"
[
  {
    "type": "form",
    "title": "尝试提交表单",
    "api": "/api/mock2/form/x",
    "body": [
      {
        "type": "input-text",
        "name": "name",
        "label": "姓名",
        "value": "amis"
      },
      {
        "type": "input-text",
        "name": "email",
        "label": "邮箱",
        "value": "amis@baidu.com"
      }
    ],
    "onEvent": {
      "submitFail": {
        "actions": [
          {
            "actionType": "setValue",
            "componentId": "submit_fail_text",
            "args": {
              "value": "${event.data.error|json}"
            }
          }
        ]
      }
    }
  },
  {
    "type": "input-text",
    "id": "submit_fail_text",
    "static": true,
    "name": "tip",
    "label": "上下文"
  }
]
```

### initApiFinished

> 6.13.0 起开始支持此事件

initApi 请求完成后触发，包括初始化过程和后续的重新刷新都会触发

可以通过 `event.data.__trigger` 来判断，它的分别是 `init` 和 `reload`。

```schema: scope="body"
[
  {
    "type": "form",
    "title": "尝试提交表单",
    "initApi": "/api/mock2/page/initData",
    "id": "theform",
    "actions": [
      {
        "label": "Reload",
        type: "button",
        onEvent: {
          click: {
            actions: [
              {
                actionType: "reload",
                componentId: "theform"
              }
            ]
          }
        }
      }
    ],
    "body": [
      {
        "type": "input-text",
        "name": "name",
        "label": "姓名"
      },
      {
        "type": "input-email",
        "name": "email",
        "label": "邮箱"
      }
    ],
    "onEvent": {
      "initApiFinished": {
        "actions": [
          {
            "actionType": "toast",
            "args": {
              "msgType": "info",
              "msg": "context: ${event.data|json} trigger: ${event.data.__trigger}"
            }
          }
        ]
      }
    }
  }
]
```

### asyncApiFinished

```schema: scope="body"
[
  {
    "type": "form",
    "title": "尝试提交表单",
    "api": "/api/mock2/form/saveForm",
    "asyncApi": {
      "url": "/api/mock2/page/initData",
      "mockResponse": {
        "status": 200,
        "data": {
          "status": 0,
          "msg": 'ok',
          "data": {
            id: 2,
            finished: true
          }
        }
      }
    },
    "body": [
      {
        "type": "input-text",
        "name": "name",
        "label": "姓名"
      },
      {
        "type": "input-email",
        "name": "email",
        "label": "邮箱"
      }
    ],
    "onEvent": {
      "asyncApiFinished": {
        "actions": [
          {
            "actionType": "setValue",
            "componentId": "async_finished_text",
            "args": {
              "value": "${event.data|json}"
            }
          }
        ]
      }
    }
  },
  {
    "type": "input-text",
    "id": "async_finished_text",
    "static": true,
    "name": "tip",
    "label": "上下文"
  }
]
```

## 动作表

当前组件对外暴露以下特性动作，其他组件可以通过指定`actionType: 动作名称`、`componentId: 该组件id`来触发这些动作，动作配置可以通过`args: {动作配置项名称: xxx}`来配置具体的参数，详细请查看[事件动作](../../docs/concepts/event-action#触发其他组件的动作)。

| 动作名称         | 动作配置                                                                                                  | 说明                       |
| ---------------- | --------------------------------------------------------------------------------------------------------- | -------------------------- |
| validate         | `outputVar: string` 校验结果，默认为 validateResult                                                       | 校验表单                   |
| submit           | `outputVar: string` 提交结果，默认为 submitResult                                                         | 提交表单                   |
| setValue         | `value: object` 更新的表单数据                                                                            | 更新数据，对数据进行 merge |
| reload           | -                                                                                                         | 刷新（重新加载）           |
| reset            | -                                                                                                         | 重置表单                   |
| clear            | -                                                                                                         | 清空表单                   |
| static           | -                                                                                                         | 表单切换为静态展示         |
| nonstatic        | -                                                                                                         | 表单切换为普通输入态       |
| validateFormItem | `componentId: string` 要校验的表单项的 id;<br>`outputVar: string` 校验结果，默认为 validateFormItemResult | 校验表单项                 |

### validate

校验结果默认缓存在`${event.data.validateResult}`，`true`表示校验成功，`false`表示检验失败。可以通过添加`outputVar`配置来修改缓存的变量。

校验结果的结构如下：

```json
{
  // 是否成功。非空表示失败
  "error": "依赖的部分字段没有通过验证",
  // 表单项报错信息。key值为该表单项的name值
  "errors": {
    "email": ["Email 格式不正确"],
    ...
  },
  // 提交验证的表单数据
  "payload": {
    "name": "amis",
    "email": "amis@baidu"
  }
}
```

```schema: scope="body"
[
  {
    "type": "button",
    "label": "校验表单",
    className: "mb-2",
    "onEvent": {
        "click": {
            "actions": [
              {
                "actionType": "validate",
                "componentId": "form_validate",
                "outputVar": "form_validate_result"
              },
              {
                "actionType": "setValue",
                "componentId": "validate_info",
                "args": {
                  "value": "${event.data.form_validate_result|json}"
                }
              }
            ]
        }
    }
  },
  {
    type: 'input-text',
    name: 'validate_info',
    id: 'validate_info',
    label: '校验结果：',
    static: true
  },
  {
    "type": "form",
    "id": "form_validate",
    "api": "/api/mock2/form/saveForm",
    "body": [
      {
        "type": "input-text",
        "name": "name",
        "label": "姓名：",
        "required": true
      },
      {
        "name": "email",
        "type": "input-text",
        "label": "邮箱：",
        "required": true,
        "validations": {
          "isEmail": true
        }
      }
    ]
  }
]
```

### submit

提交结果默认缓存在`${event.data.submitResult}`，可以通过添加`outputVar`配置来修改缓存的变量。

提交结果的结构如下：

```json
{
  // 是否成功。是否成功。非空表示失败
  "error": "依赖的部分字段没有通过验证",
  // 错误信息。如果是校验失败，则errors为表单项报错信息，key值为该表单项的name值
  "errors": {
    ...
  },
  // 提交的表单数据
  "payload": {
    "name": "amis",
    "email": "amis@baidu.com"
  },
  // 提交请求返回的响应结果数据
  "responseData": {
    "id": "1"
  }
}
```

```schema: scope="body"
[
  {
    "type": "button",
    "label": "提交表单",
    className: "mb-2",
    "onEvent": {
        "click": {
            "actions": [
              {
                "actionType": "submit",
                "componentId": "form_submit",
                "outputVar": "form_submit_result"
              },
              {
                "actionType": "setValue",
                "componentId": "submit_info",
                "args": {
                  "value": "${event.data.form_submit_result|json}"
                }
              }
            ]
        }
    }
  },
  {
    type: 'input-text',
    name: 'submit_info',
    id: 'submit_info',
    label: '提交结果：',
    static: true
  },
  {
    "type": "form",
    "id": "form_submit",
    "api": "/api/mock2/form/saveForm",
    "body": [
      {
        "type": "input-text",
        "name": "name",
        "label": "姓名：",
        "required": true
      },
      {
        "name": "email",
        "type": "input-text",
        "label": "邮箱：",
        "required": true,
        "validations": {
          "isEmail": true
        }
      }
    ]
  }
]
```

### setValue

通过`setValue`更新指定表单的数据。

#### 合并数据

默认`setValue`会将新数据与目标组件数据进行合并。

```schema: scope="body"
[
  {
    "type": "button",
    "label": "修改表单数据",
    className: "mb-2",
    "onEvent": {
        "click": {
            "actions": [
              {
                "actionType": "setValue",
                "componentId": "form_setvalue",
                "args": {
                  "value": {
                    "name": "aisuda",
                    "email": "aisuda@baidu.com"
                  }
                }
              }
            ]
        }
    }
  },
  {
    "type": "form",
    "id": "form_setvalue",
    "data": {
      "name": "amis",
      "email": "amis@baidu.com"
    },
    "body": [
      {
        "type": "input-text",
        "name": "name",
        "label": "姓名："
      },
      {
        "name": "email",
        "type": "input-text",
        "label": "邮箱："
      }
    ]
  }
]
```

#### 覆盖数据

可以通过`"dateMergeMode": "override"`来覆盖目标组件数据。

```schema: scope="body"
[
  {
    "type": "button",
    "label": "修改表单数据",
    className: "mb-2",
    "onEvent": {
        "click": {
            "actions": [
              {
                "actionType": "setValue",
                "componentId": "form_setvalue",
                "args": {
                  "value": {
                    "name": "aisuda"
                  }
                },
                "dataMergeMode": "override"
              }
            ]
        }
    }
  },
  {
    "type": "form",
    "id": "form_setvalue",
    "data": {
      "name": "amis",
      "email": "amis@baidu.com"
    },
    "body": [
      {
        "type": "input-text",
        "name": "name",
        "label": "姓名："
      },
      {
        "name": "email",
        "type": "input-text",
        "label": "邮箱："
      }
    ]
  }
]
```

### reload

#### 只做刷新

重新发送`initApi`请求，刷新 Form 时，只配置`componentId`目标组件 ID 即可。

```schema: scope="body"
[
  {
    "type": "button",
    "label": "刷新表单",
    className: "mb-2",
    "onEvent": {
        "click": {
            "actions": [
              {
                "actionType": "reload",
                "componentId": "form_reload"
              }
            ]
        }
    }
  },
  {
    "type": "form",
    "id": "form_reload",
    "debug": true,
    "initApi": "/api/mock2/form/initData",
    "body": [
      {
        "type": "input-text",
        "name": "name",
        "label": "姓名："
      },
      {
        "name": "author",
        "type": "input-text",
        "label": "作者："
      }
    ]
  }
]
```

#### 发送数据并刷新

刷新 Form 组件时，如果配置了`data`，将发送`data`给目标组件，并将该数据合并到目标组件的数据域中（如果配置`"dataMergeMode": "override"`将覆盖目标组件的数据），然后重新请求数据。

```schema: scope="body"
[
  {
    "type": "button",
    "label": "刷新Form数据加载请求，并将我的年龄设置为18",
    className: "mb-2",
    "onEvent": {
        "click": {
            "actions": [
              {
                "actionType": "reload",
                "componentId": "form_reload2",
                "data": {
                  age: 18
                }
              }
            ]
        }
    }
  },
  {
    "type": "form",
    "id": "form_reload2",
    "debug": true,
    "initApi": "/api/mock2/form/initData",
    "body": [
      {
        "type": "input-text",
        "name": "name",
        "label": "姓名："
      },
      {
        "name": "author",
        "type": "input-text",
        "label": "作者："
      },
      {
        "name": "age",
        "type": "input-text",
        "label": "年龄："
      }
    ]
  }
]
```

### reset

通过`reset`将表单数据重置为初始数据，初始数据可以是静态数据或初始化接口返回的数据。

```schema: scope="body"
[
  {
    "type": "button",
    "label": "重置表单",
    className: "mb-2",
    "onEvent": {
        "click": {
            "actions": [
              {
                "actionType": "reset",
                "componentId": "form_reset"
              }
            ]
        }
    }
  },
  {
    "type": "form",
    "id": "form_reset",
    "initApi": "/api/mock2/form/initData",
    "body": [
      {
        "type": "alert",
        "body": "修改表单项的值，然后点击【重置表单】，表单数据将被重置为初始化数据"
      },
      {
        "type": "input-text",
        "name": "name",
        "label": "姓名："
      },
      {
        "name": "author",
        "type": "input-text",
        "label": "作者："
      }
    ]
  }
]
```

### clear

通过`clear`来清空表单中的表单项数据，不包含`hidden`类型、未绑定表单项的初始化数据字段。

```schema: scope="body"
[
  {
    "type": "button",
    "label": "清空表单",
    className: "mb-2",
    "onEvent": {
        "click": {
            "actions": [
              {
                "actionType": "clear",
                "componentId": "form_clear"
              }
            ]
        }
    }
  },
  {
    "type": "form",
    "id": "form_clear",
    "debug": true,
    "initApi": "/api/mock2/form/initData",
    "body": [
      {
        "type": "input-text",
        "name": "name",
        "label": "姓名："
      },
      {
        "name": "author",
        "type": "hidden",
        "label": "作者："
      }
    ]
  }
]
```

### static 和 nonstatic

```schema: scope="body"
[
  {
    "type": "button",
    "label": "静态模式",
    "className": "mr-2 mb-2",
    "onEvent": {
      "click": {
        "actions": [
          {
            "actionType": "static",
            "componentId": "form_static"
          }
        ]
      }
    }
  },
  {
    "type": "button",
    "label": "非静态模式",
    "className": "mr-2 mb-2",
    "onEvent": {
      "click": {
        "actions": [
          {
            "actionType": "nonstatic",
            "componentId": "form_static"
          }
        ]
      }
    }
  },
  {
    "type": "form",
    "id": "form_static",
    "title": "表单",
    "body": [
      {
        "type": "input-text",
        "name": "text",
        "label": "输入框",
        "mode": "horizontal",
        "value": "text"
      }
    ]
  }
]
```

### validateFormItem

> 3.6.4 及以上版本

对单个表单项进行校验，通过配置`actionType: 'validateFormItem'`实现表单项的校验  
校验结果默认缓存在`${event.data.validateFormItemResult}`中，可以通过添加`outputVar`配置来修改缓存的变量

校验结果的结构如下：

```json
{
  // 校验结果，非空表示失败
  "error": "错误信息",
  // 校验的表单项的值
  "value": ""
}
```

```schema
{
  type: 'page',
  title: '更新表单数据',
  body: [
    {
      type: 'form',
      title: '表单',
      wrapWithPanel: false,
      body: [
        {
          type: 'input-text',
          label: '必填项',
          name: 'required',
          id: 'required',
          required: true
        }
      ]
    },
    {
      "type": "input-text",
      "name": "validate_info",
      "id": "validate_info",
      "label": "校验结果：",
      "static": true
    },
    {
      type: 'button',
      label: '校验',
      level: 'primary',
      className: 'mt-2',
      onEvent: {
        click: {
          actions: [
            {
              actionType: 'validateFormItem',
              componentId: 'required'
            },
            {
              "actionType": "setValue",
              "componentId": "validate_info",
              "args": {
                "value": "${event.data.validateFormItemResult|json}"
              }
            }
          ]
        }
      }
    }
  ]
}
```

### clearError

> 6.11.1 及以上版本
> 清除表单校验产生的错误状态

```schema
{
  type: 'page',
  title: '清除表单错误',
  body: [
    {
      type: 'form',
      title: '表单',
      id: 'form',
      body: [
        {
          type: 'input-text',
          label: '必填项',
          name: 'required',
          required: true
        }
      ]
    },
    {
      type: 'button',
      label: '清除错误',
      level: 'primary',
      onEvent: {
        click: {
          actions: [
            {
              actionType: 'clearError',
              componentId: 'form'
            }
          ]
        }
      }
    }
  ]
}
```

---

### Zh CN Components Action (`docs/zh-CN/components/action.md`)

---
title: Action 行为按钮
description:
type: 0
group: ⚙ 组件
menuName: Action 行为按钮
icon:
order: 26
---

Action 行为按钮，是触发页面行为的主要方法之一

## 基本用法

我们这里简单实现一个点击按钮弹框的交互。

```schema: scope="body"
{
  "label": "弹框",
  "type": "button",
  "actionType": "dialog",
  "dialog": {
    "title": "弹框",
    "body": "这是个简单的弹框。"
  }
}
```

## 样式

### 尺寸

配置`size`，显示不同尺寸

```schema: scope="body"
{
  "type": "button-toolbar",
  "buttons": [
    {
      "type": "button",
      "label": "默认尺寸"
    },
    {
      "type": "button",
      "label": "极小",
      "size": "xs"
    },
    {
      "type": "button",
      "label": "小",
      "size": "sm"
    },
    {
      "type": "button",
      "label": "中等",
      "size": "md"
    },
    {
      "type": "button",
      "label": "大",
      "size": "lg"
    }
  ]
}
```

### 主题

可以配置`level`或者`primary`，显示不同样式。

```schema: scope="body"
{
  "type": "button-toolbar",
  "buttons": [
    {
      "type": "button",
      "label": "默认"
    },
    {
      "type": "button",
      "label": "主要",
      "level": "primary"
    },
    {
      "type": "button",
      "label": "次要",
      "level": "secondary"
    },
    {
      "type": "button",
      "label": "信息",
      "level": "info"
    },
    {
      "type": "button",
      "label": "成功",
      "level": "success"
    },
    {
      "type": "button",
      "label": "警告",
      "level": "warning"
    },
    {
      "type": "button",
      "label": "危险",
      "level": "danger"
    },
    {
      "type": "button",
      "label": "浅色",
      "level": "light"
    },
    {
      "type": "button",
      "label": "深色",
      "level": "dark"
    },
    {
      "type": "button",
      "label": "链接",
      "level": "link"
    }
  ]
}
```

### 图标

可以配置`icon`配置项，实现按钮显示图标

```schema: scope="body"
{
  "label": "弹框",
  "type": "button",
  "actionType": "dialog",
  "icon": "fa fa-plus",
  "dialog": {
    "title": "弹框",
    "body": "这是个简单的弹框。"
  }
}
```

icon 也可以是 url 地址，比如

```schema: scope="body"
{
  "label": "弹框",
  "type": "button",
  "actionType": "dialog",
  "icon": "https://suda.cdn.bcebos.com/images%2F2021-01%2Fdiamond.svg",
  "dialog": {
    "title": "弹框",
    "body": "这是个简单的弹框。"
  }
}
```

如果`label`配置为空字符串，可以只显示`icon`

```schema: scope="body"
{
  "label": "",
  "type": "button",
  "actionType": "dialog",
  "icon": "fa fa-plus",
  "dialog": {
    "title": "弹框",
    "body": "这是个简单的弹框。"
  }
}
```

## 操作前确认

可以通过配置`confirmText`，实现在任意操作前，弹出提示框确认是否进行该操作。同时可以通过配置 `confirmTitle` 来设置弹窗标题

```schema: scope="body"
{
    "label": "ajax请求",
    "type": "button",
    "actionType": "ajax",
    "confirmText": "确认要发出这个请求？",
    "confirmTitle": "炸弹",
    "api": "/api/mock2/form/saveForm"
}
```

## ajax 请求

通过配置`"actionType":"ajax"`和`api`，可以实现 ajax 请求。

```schema: scope="body"
{
    "label": "ajax请求",
    "type": "button",
    "actionType": "ajax",
    "api": "/api/mock2/form/saveForm"
}
```

### 请求成功后，跳转至某个页面

##### 配置相对路径，实现单页跳转

```schema: scope="body"
{
    "label": "ajax请求",
    "type": "button",
    "actionType": "ajax",
    "api": "/api/mock2/form/saveForm",
    "redirect": "../docs/start/getting-started"
}
```

##### 配置完整路径，直接跳转指定路径

```schema: scope="body"
{
    "label": "ajax请求",
    "type": "button",
    "actionType": "ajax",
    "api": "/api/mock2/form/saveForm",
    "redirect": "https://www.baidu.com/"
}
```

### 请求成功后，显示反馈弹框

```schema: scope="body"
{
    "type": "button",
    "label": "ajax 反馈弹框",
    "actionType": "ajax",
    "api": "/api/mock2/form/saveForm",
    "feedback": {
        "title": "操作成功",
        "body": "${id} 已操作成功"
    }
}
```

更多内容查看[Dialog 文档](./dialog#feedback-%E5%8F%8D%E9%A6%88%E5%BC%B9%E6%A1%86)

### 请求成功后，刷新目标组件

1. 目标组件需要配置 `name` 属性
2. Action 上添加 `"reload": "xxx"`，`xxx` 为目标组件的 `name` 属性值，如果配置多个组件，`name` 用逗号分隔，另外如果想让 reload 的时候再携带些数据可以类似这样配置 `{"reload": "xxx?a=${a}&b=${b}"}`, 这样不仅让目标组件刷新，同时还会把当前环境中的数据 a 和 b 传递给 xxx.

```schema
{
  "type": "page",
  "body": [
    {
      "type": "button",
      "label": "ajax 请求",
      "actionType": "ajax",
      "api": "/api/mock2/form/saveForm",
      "reload": "crud"
    },
    {
      "type": "divider"
    },
    {
      "type": "crud",
      "name": "crud",
      "api": "/api/mock2/sample?waitSeconds=1",
      "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "engine",
            "label": "Rendering engine"
        },
        {
            "name": "browser",
            "label": "Browser"
        },
        {
            "name": "platform",
            "label": "Platform(s)"
        },
        {
            "name": "version",
            "label": "Engine version"
        },
        {
            "name": "grade",
            "label": "CSS grade"
        }
      ]
    }
  ]
}
```

> 配置 `"reload": "window"` 可刷新当前页面

### 自定义 toast 文字

可以通过配置`messages`，自定义接口返回`toast`信息

```schema: scope="body"
{
    "type": "button",
    "label": "ajax 请求",
    "actionType": "ajax",
    "api": "/api/mapping",
    "messages": {
        "success": "成功了！欧耶",
        "failed": "失败了呢。。"
    }
}
```

需要注意如果 api 结果返回了 `msg` 字段，会优先使用 api 的返回。

**属性表**

| 属性名   | 类型                                                                                     | 默认值 | 说明                                                                                                                                   |
| -------- | ---------------------------------------------------------------------------------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------- |
| api      | [Api](../../docs/types/api)                                                              | -      | 请求地址，参考 [api](../../docs/types/api) 格式说明。                                                                                  |
| redirect | [模板字符串](../../docs/concepts/template#%E6%A8%A1%E6%9D%BF%E5%AD%97%E7%AC%A6%E4%B8%B2) | -      | 指定当前请求结束后跳转的路径，可用 `${xxx}` 取值。                                                                                     |
| feedback | `DialogObject`                                                                           | -      | 如果 ajax 类型的，当 ajax 返回正常后，还能接着弹出一个 dialog 做其他交互。返回的数据可用于这个 dialog 中。格式可参考[Dialog](./Dialog) |
| messages | `object`                                                                                 | -      | `success`：ajax 操作成功后提示，可以不指定，不指定时以 api 返回为准。`failed`：ajax 操作失败提示。                                     |

## 下载请求

> 1.4.0 及以上版本

通过配置 `"actionType":"download"` 和 `api`，可以实现下载请求，它其实是 `ajax` 的一种特例，自动给 api 加上了 `"responseType": "blob"`。

> 3.5.0 版本开始可以配置 `downloadFileName` 来覆盖下载文件名。注意：即便配置了 `downloadFileName`，api 依然需要返回 `Content-Disposition` 头。

```schema: scope="body"
{
    "label": "下载",
    "type": "action",
    "actionType": "download",
    "api": "/api/download"
}
```

上面的例子由于环境原因没法测试，需要在返回的 header 中配置 `content-type` 和 `Content-Disposition`，比如

```
Content-Type: application/pdf
Content-Disposition: attachment; filename="download.pdf"
```

如果接口存在跨域，除了常见的 cors header 外，还需要添加以下 header

```
Access-Control-Expose-Headers:  Content-Disposition
```

## 保存到本地

> 1.10.0 及以上版本

和前面的下载接口功能类似，但不需要返回 `Content-Disposition` header，只需要解决跨域问题，主要用于一些简单的场景，比如下载文本

```schema: scope="body"
{
    "label": "保存",
    "type": "action",
    "actionType": "saveAs",
    "api": "/api/download"
}
```

> 这个功能目前还没用到 env 里的 fetcher 方法，不支持 POST

默认会自动取 url 中的文件名，如果没有的话就需要指定，比如

```schema: scope="body"
{
    "label": "保存",
    "type": "action",
    "actionType": "saveAs",
    "fileName": "下载的文件名",
    "api": "/api/download"
}
```

## 倒计时

主要用于发验证码的场景，通过设置倒计时 `countDown`（单位是秒），让点击按钮后禁用一段时间：

> 如果同时使用多个倒计时组件时, 需要额外配置全局唯一的`name`或`id`属性, 避免多个组件之间的计时器冲突

```schema: scope="body"
{
  "type": "form",
  "body": [
    {
      "name": "phone",
      "type": "input-text",
      "required": true,
      "label": "手机号",
      "addOn": {
        "name": "countdown1",
        "label": "发送验证码",
        "type": "button",
        "countDown": 60,
        "countDownTpl": "${timeLeft} 秒后重发",
        "actionType": "ajax",
        "api": "/api/mock2/form/saveForm?phone=${phone}"
      }
    }
  ]
}
```

同时还能通过 `countDownTpl` 来控制显示的文本，其中 `${timeLeft}` 变量是剩余时间。

## 跳转链接

### 单页跳转

```schema: scope="body"
{
    "label": "进入介绍页",
    "type": "button",
    "level": "info",
    "actionType": "link",
    "link": "../docs/index"
}

```

**属性表**

| 属性名     | 类型     | 默认值 | 说明                                                                                                                |
| ---------- | -------- | ------ | ------------------------------------------------------------------------------------------------------------------- |
| actionType | `string` | `link` | 单页跳转                                                                                                            |
| link       | `string` | `link` | 用来指定跳转地址，跟 url 不同的是，这是单页跳转方式，不会渲染浏览器，请指定 amis 平台内的页面。可用 `${xxx}` 取值。 |

### 直接跳转

```schema: scope="body"
{
    "label": "打开 Baidu",
    "type": "button",
    "level": "success",
    "actionType": "url",
    "url": "http://www.baidu.com"
}
```

**属性表**

| 属性名     | 类型      | 默认值  | 说明                                             |
| ---------- | --------- | ------- | ------------------------------------------------ |
| actionType | `string`  | `url`   | 页面跳转                                         |
| url        | `string`  | -       | 按钮点击后，会打开指定页面。可用 `${xxx}` 取值。 |
| blank      | `boolean` | `false` | 如果为 `true` 将在新 tab 页面打开。              |

## 发送邮件

```schema: scope="body"
{
  "label": "发送邮件",
  "type": "button",
  "actionType": "email",
  "to": "amis@baidu.com",
  "cc": "baidu@baidu.com",
  "subject": "这是邮件主题",
  "body": "这是邮件正文"
}
```

### 异步获取数据

```schema: scope="body"
{
  "type": "page",
  "initApi": "/api/mock2/mail/mailInfo",
  "body": {
    "label": "发送邮件",
    "type": "button",
    "actionType": "email",
    "to": "${to}",
    "cc": "${cc}",
    "subject": "${subject}",
    "body": "${body}"
  }
}
```

**属性表**

| 属性名     | 类型     | 默认值  | 说明                             |
| ---------- | -------- | ------- | -------------------------------- |
| actionType | `string` | `email` | 点击后显示一个弹出框             |
| to         | `string` | -       | 收件人邮箱，可用 ${xxx} 取值。   |
| cc         | `string` | -       | 抄送邮箱，可用 ${xxx} 取值。     |
| bcc        | `string` | -       | 匿名抄送邮箱，可用 ${xxx} 取值。 |
| subject    | `string` | -       | 邮件主题，可用 ${xxx} 取值。     |
| body       | `string` | -       | 邮件正文，可用 ${xxx} 取值。     |

## 弹框

```schema: scope="body"
{
  "label": "Dialog Form",
  "type": "button",
  "level": "primary",
  "actionType": "dialog",
  "dialog": {
    "title": "表单设置",
    "body": {
      "type": "form",
      "api": "/api/mock2/form/saveForm",
      "body": [
        {
          "type": "input-text",
          "name": "text",
          "label": "文本"
        }
      ]
    }
  }
}
```

### 弹框结合 reload 刷新下拉框的例子

下面是一种典型场景，有个一个下拉框，然后有个按钮能弹框新增数据，新增了之后需要下拉框重新拉取最新列表（这个例子因为没实现新增功能，所以看不出更新，如果看网络请求会发现重新请求了一次）。

```schema: scope="body"
{
    "type": "form",
    "api": "/api/mock2/form/saveForm",
    "name": "myForm",
    "body": [
        {
          "type": "select",
          "name": "group",
          "label": "分组",
          "source": "/api/mock2/form/getOptions"
        },
        {
          "label": "新增分组",
          "type": "button",
          "level": "primary",
          "actionType": "dialog",
          "reload": "myForm.group",
          "dialog": {
            "title": "新增分组",
            "body": {
              "type": "form",
              "api": "/api/mock2/form/saveForm",
              "body": [
                {
                  "type": "input-text",
                  "name": "groupName",
                  "label": "分组名"
                }
              ]
            }
          }
        }
    ]
}
```

可以看到 `reload` 是 `myForm.group`，第一个是表单的 name，第二个是下拉框的 name。

**属性表**

| 属性名        | 类型                       | 默认值   | 说明                                          |
| ------------- | -------------------------- | -------- | --------------------------------------------- |
| actionType    | `string`                   | `dialog` | 点击后显示一个弹出框                          |
| dialog        | `string` 或 `DialogObject` | -        | 指定弹框内容，格式可参考[Dialog](./dialog)    |
| nextCondition | `boolean`                  | -        | 可以用来设置下一条数据的条件，默认为 `true`。 |

## 抽屉

```schema: scope="body"
{
  "label": "Drawer Form",
  "type": "button",
  "actionType": "drawer",
  "drawer": {
    "title": "表单设置",
    "body": {
      "type": "form",
      "api": "/api/mock2/form/saveForm?waitSeconds=1",
      "body": [
        {
          "type": "input-text",
          "name": "text",
          "label": "文本"
        }
      ]
    }
  }
}
```

**属性表**

| 属性名     | 类型                       | 默认值   | 说明                                       |
| ---------- | -------------------------- | -------- | ------------------------------------------ |
| actionType | `string`                   | `drawer` | 点击后显示一个侧边栏                       |
| drawer     | `string` 或 `DrawerObject` | -        | 指定弹框内容，格式可参考[Drawer](./drawer) |

## 复制文本

```schema: scope="body"
{
    "label": "复制一段文本",
    "type": "button",
    "actionType": "copy",
    "content": "http://www.baidu.com"
}
```

可以通过 `copyFormat` 设置复制的格式，默认是文本

```schema: scope="body"
{
    "label": "复制一段富文本",
    "type": "button",
    "actionType": "copy",
    "copyFormat": "text/html",
    "content": "<a href='http://www.baidu.com'>link</a> <b>bold</b>"
}
```

**属性表**

| 属性名     | 类型                                 | 默认值 | 说明                                 |
| ---------- | ------------------------------------ | ------ | ------------------------------------ |
| actionType | `string`                             | `copy` | 复制一段内容到粘贴板                 |
| content    | [模板](../../docs/concepts/template) | -      | 指定复制的内容。可用 `${xxx}` 取值。 |

## 刷新其他组件

**属性表**

| 属性名     | 类型     | 默认值   | 说明                                                                        |
| ---------- | -------- | -------- | --------------------------------------------------------------------------- |
| actionType | `string` | `reload` | 刷新目标组件                                                                |
| target     | `string` | -        | 需要刷新的目标组件名字（组件的`name`值，自己配置的），多个请用 `,` 号隔开。 |

## 组件特有的行为类型

### 表单中表格添加一行

该 actionType 为[FormItem-Table](./form/input-table#按钮触发新增行)专用行为

### 校验表单

下面的表单中会优先校验按钮`required`属性包含的表单项，当所有的字段校验完毕后，才会校验表单中固有的项目。需要额外注意的是，当按钮中的 `required` 和对应表单项本身的 `required` 属性冲突时，最终校验方式是`"required": true`。

```
/* Detailed source-code truncated for AI context efficiency. */
```

### 重置表单

在 form 中，配置`"type": "reset"`的按钮，可以实现重置表单数据的功能

```schema: scope="body"
{
    "type": "form",
    "api": "/api/mock2/form/saveForm",
    "body": [
        {
            "type": "input-text",
            "name": "username",
            "placeholder": "请输入用户名",
            "label": "用户名"
        },
        {
            "type": "input-password",
            "name": "password",
            "label": "密码",
            "placeholder": "请输入密码"
        },
        {
            "type": "checkbox",
            "name": "rememberMe",
            "option": "记住登录"
        }
    ],
    "actions": [
        {
            "type": "reset",
            "label": "重置"
        },
        {
            "type": "submit",
            "label": "提交",
            "level": "primary"
        }
    ]
}
```

### 清空表单

在 form 中，配置`"actionType": "clear"`的按钮，可以实现清空表单数据的功能，跟重置不同的是，重置其实是还原到初始值，并不一定是清空。

```schema: scope="body"
{
    "type": "form",
    "api": "/api/mock2/form/saveForm",
    "body": [
        {
            "type": "input-text",
            "name": "username",
            "placeholder": "请输入用户名",
            "label": "用户名",
            "value": "rick"
        },
        {
            "type": "input-password",
            "name": "password",
            "label": "密码",
            "placeholder": "请输入密码"
        },
        {
            "type": "checkbox",
            "name": "rememberMe",
            "option": "记住登录"
        }
    ],
    "actions": [
        {
            "type": "button",
            "actionType": "clear",
            "label": "清空"
        },
        {
            "type": "reset",
            "label": "重置"
        },
        {
            "type": "submit",
            "label": "提交",
            "level": "primary"
        }
    ]
}
```

### 重置表单并提交

`actionType` 配置成 `"reset-and-submit"`

### 清空表单并提交

`actionType` 配置成 `"clear-and-submit"`

## 自定义点击事件

> 1.3.0 版本新增功能

如果上面的行为不满足需求，还可以通过字符串形式的 `onClick` 来定义点击事件，这个字符串会转成 JavaScript 函数，并支持异步（如果是用 sdk 需要自己编译一个 es2017 版本）。

```schema: scope="body"
{
    "label": "点击",
    "type": "button",
    "onClick": "alert('点击了按钮'); console.log(props);"
}
```

amis 会传入两个参数 `event` 和 `props`，`event` 就是 React 的事件，而 `props` 可以拿到这个组件的其他属性，同时还能调用 amis 中的内部方法。

```schema: scope="body"
{
    "label": "点击",
    "type": "button",
    "onClick": "props.onAction(event, {actionType:'dialog', dialog: {title: '弹框', body: '这是代码调用的弹框'}})"
}
```

我们将前面的代码拿出来方便分析：

```javascript
// event 和 props 前面提到过，而 onAction 就是 amis 内部的方法，可以用来调用其他 action，需要传递两个参数，一个是 event，另一个就是 action 类型及所需的参数。
props.onAction(event, {
  actionType: 'dialog',
  dialog: {title: '弹框', body: '这是代码调用的弹框'}
});
```

这个函数如果返回 `false` 就会阻止 amis 其他 action 的执行，比如这个例子

```schema: scope="body"
{
  "label": "弹框",
  "type": "button",
  "actionType": "dialog",
  "onClick": "alert('点击按钮');",
  "dialog": {
    "title": "弹框",
    "body": "这是个简单的弹框。"
  }
}
```

它的行为是先执行 alert，再执行弹框，但如果我们加上一个 `return false`，就会发现后面的 amis 弹框不执行了。

```schema: scope="body"
{
  "label": "弹框",
  "type": "button",
  "actionType": "dialog",
  "onClick": "alert('点击按钮'); return false;",
  "dialog": {
    "title": "弹框",
    "body": "这是个简单的弹框。"
  }
}
```

如果是在表单项中，还能通过 `props.formStore.setValues();` 来修改其它表单项值

```schema: scope="body"
{
  "type": "form",
  "api": "/api/mock2/form/saveForm",
  "body": [
    {
      "type": "input-text",
      "name": "name",
      "label": "姓名："
    },
    {
      "type": "input-text",
      "name": "email",
      "label": "邮箱："
    },
    {
      "label": "修改姓名",
      "name": "name",
      "type": "button",
      "onClick": "props.formStore.setValues({name: 'amis', email: 'amis@baidu.com'});"
    }
  ]
}
```

## 全局键盘快捷键触发

> 1.3.0 版本新增功能

可以通过 `hotKey` 属性来配置键盘快捷键触发，比如下面的例子

```schema: scope="body"
{
  "label": "使用 ⌘+o 或 ctrl+o 来弹框",
  "type": "button",
  "hotKey": "command+o,ctrl+o",
  "actionType": "dialog",
  "dialog": {
    "title": "弹框",
    "body": "这是个简单的弹框。"
  }
}
```

除了 ctrl 和 command 还支持 shift、alt。

其它键盘特殊按键的命名列表：backspace, tab, clear, enter, return, esc, escape, space, up, down, left, right, home, end, pageup, pagedown, del, delete, f1 - f19, num_0 - num_9, num_multiply, num_add, num_enter, num_subtract, num_decimal, num_divide。

> 注意这个主要用于实现页面级别快捷键，如果要实现回车提交功能，请将 `input-text` 放在 `form` 里，而不是给 button 配一个 `enter` 的快捷键。

## Action 作为容器组件

> 1.5.0 及以上版本

action 还可以使用 `body` 来渲染其他组件，让那些不支持行为的组件支持点击事件，比如下面的例子

```schema: scope="body"
[{
  "type": "action",
  "body": [{
    "type": "color",
    "value": "#108cee"
  }],
  "actionType": "dialog",
  "dialog": {
    "title": "弹框",
    "body": "这是个简单的弹框。"
  }
},{
  "type": "action",
  "body": {
    "type": "image",
    "src": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,w_216,l_1,f_jpg,q_80"
  },
  "tooltip": "点击会有弹框",
  "actionType": "dialog",
  "dialog": {
    "title": "弹框",
    "body": "这是个简单的弹框。"
  }
}]
```

在这种模式下不支持按钮的各种配置项，比如 `label`、`size`、`icon` 等，因为它只作为容器组件，没有展现。

## 按钮提示

通过 `tooltip` 来设置提示

```schema: scope="body"
{
  "label": "弹框",
  "type": "button",
  "actionType": "link",
  "link": "../index",
  "tooltip": "点击链接跳转"
}
```

如果按钮是 disabled，需要使用 `disabledTip`

```schema: scope="body"
{
  "label": "弹框",
  "type": "button",
  "actionType": "link",
  "disabled": true,
  "link": "../index",
  "disabledTip": "禁用了"
}
```

还可以通过 `tooltipPlacement` 设置弹出位置

```schema: scope="body"
{
  "label": "弹框",
  "type": "button",
  "actionType": "link",
  "link": "../index",
  "tooltipPlacement": "right",
  "tooltip": "点击链接跳转"
}
```

## 通用属性表

所有`actionType`都支持的通用配置项

| 属性名             | 类型                                 | 默认值      | 说明                                                                                                                                                                        |
| ------------------ | ------------------------------------ | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| type               | `string`                             | `action`    | 指定为 Page 渲染器。                                                                                                                                                        |
| actionType         | `string`                             | -           | 【必填】这是 action 最核心的配置，来指定该 action 的作用类型，支持：`ajax`、`link`、`url`、`drawer`、`dialog`、`confirm`、`cancel`、`prev`、`next`、`copy`、`close`。       |
| label              | `string`                             | -           | 按钮文本。可用 `${xxx}` 取值。                                                                                                                                              |
| level              | `string`                             | `default`   | 按钮样式，支持：`link`、`primary`、`secondary`、`info`、`success`、`warning`、`danger`、`light`、`dark`、`default`。                                                        |
| size               | `string`                             | -           | 按钮大小，支持：`xs`、`sm`、`md`、`lg`。                                                                                                                                    |
| icon               | `string`                             | -           | 设置图标，例如`fa fa-plus`。                                                                                                                                                |
| iconClassName      | `string`                             | -           | 给图标上添加类名。                                                                                                                                                          |
| rightIcon          | `string`                             | -           | 在按钮文本右侧设置图标，例如`fa fa-plus`。                                                                                                                                  |
| rightIconClassName | `string`                             | -           | 给右侧图标上添加类名。                                                                                                                                                      |
| active             | `boolean`                            | -           | 按钮是否高亮。                                                                                                                                                              |
| activeLevel        | `string`                             | -           | 按钮高亮时的样式，配置支持同`level`。                                                                                                                                       |
| activeClassName    | `string`                             | `is-active` | 给按钮高亮添加类名。                                                                                                                                                        |
| block              | `boolean`                            | -           | 用`display:"block"`来显示按钮。                                                                                                                                             |
| confirmText        | [模板](../../docs/concepts/template) | -           | 当设置后，操作在开始前会询问用户。可用 `${xxx}` 取值。                                                                                                                      |
| confirmTitle       | [模板](../../docs/concepts/template) | -           | 确认框标题，前提是 confirmText 有内容，支持模版语法                                                                                                                         |
| reload             | `string`                             | -           | 指定此次操作完后，需要刷新的目标组件名字（组件的`name`值，自己配置的），多个请用 `,` 号隔开。                                                                               |
| tooltip            | `string`                             | -           | 鼠标停留时弹出该段文字，也可以配置对象类型：字段为`title`和`content`。可用 `${xxx}` 取值。                                                                                  |
| disabledTip        | `'string' \| 'TooltipObject'`        | -           | 被禁用后鼠标停留时弹出该段文字，也可以配置对象类型：字段为`title`和`content`。可用 `${xxx}` 取值。                                                                          |
| tooltipPlacement   | `string`                             | `top`       | 如果配置了`tooltip`或者`disabledTip`，指定提示信息位置，可配置`top`、`bottom`、`left`、`right`。                                                                            |
| close              | `boolean` or `string`                | -           | 当`action`配置在`dialog`或`drawer`的`actions`中时，配置为`true`指定此次操作完后关闭当前`dialog`或`drawer`。当值为字符串，并且是祖先层弹框的名字的时候，会把祖先弹框关闭掉。 |
| required           | `Array<string>`                      | -           | 配置字符串数组，指定在`form`中进行操作之前，需要指定的字段名的表单项通过验证                                                                                                |

### TooltipObject

`TooltipObject` 为 [tooltip-wrapper](./tooltip) 属性配置，但是不需要配置如下属性 `type`、`body`、`wrapperComponent`、`className`、`inline`。

## 事件表

当前组件会对外派发以下事件，可以通过`onEvent`来监听这些事件，并通过`actions`来配置执行的动作，在`actions`中可以通过`${事件参数名}`或`${event.data.[事件参数名]}`来获取事件产生的数据，详细查看[事件动作](../../docs/concepts/event-action)。

| 事件名称   | 事件参数 | 说明           |
| ---------- | -------- | -------------- |
| click      | -        | 点击时触发     |
| mouseenter | -        | 鼠标移入时触发 |
| mouseleave | -        | 鼠标移出时触发 |

### click

鼠标点击。可以尝试通过`${event.context.nativeEvent}`获取鼠标事件对象。

```schema: scope="body"
{
  "type": "button",
  "label": "Button",
  "onEvent": {
    "click": {
      "actions": [
        {
          "actionType": "toast",
          "args": {
            "msgType": "info",
            "msg": "${event.context.nativeEvent.type}"
          }
        }
      ]
    }
  }
}
```

### mouseenter

鼠标移入。可以尝试通过`${event.context.nativeEvent}`获取鼠标事件对象。

```schema: scope="body"
{
  "type": "button",
  "label": "Button",
  "onEvent": {
    "mouseenter": {
      "actions": [
        {
          "actionType": "toast",
          "args": {
            "msgType": "info",
            "msg": "${event.context.nativeEvent.type}"
          }
        }
      ]
    }
  }
}
```

### mouseleave

鼠标移出。可以尝试通过`${event.context.nativeEvent}`获取鼠标事件对象。

```schema: scope="body"
{
  "type": "button",
  "label": "Button",
  "onEvent": {
    "mouseleave": {
      "actions": [
        {
          "actionType": "toast",
          "args": {
            "msgType": "info",
            "msg": "${event.context.nativeEvent.type}"
          }
        }
      ]
    }
  }
}
```

## 动作表

暂无

---

### Zh CN Components Alert (`docs/zh-CN/components/alert.md`)

---
title: Alert 提示
description:
type: 0
group: ⚙ 组件
menuName: Alert 提示
icon:
order: 27
---

用来做文字特殊提示，分为四类：提示类、成功类、警告类和危险类。

## 基本使用

`level`属性支持 4 种预设样式：`info`, `success`, `warning`, `danger`。

```schema: scope="body"
[
  {
    "type": "alert",
    "body": "提示类文案",
    "level": "info",
    "className": "mb-1"
  },
  {
    "type": "alert",
    "title": "提示类标题",
    "body": "提示类文案",
    "level": "info",
    "className": "mb-3"
  },
  {
    "type": "alert",
    "body": "成功类文案",
    "level": "success",
    "className": "mb-1"
  },
  {
    "type": "alert",
    "title": "成功类标题",
    "body": "成功类文案",
    "level": "success",
    "className": "mb-3"
  },
  {
    "type": "alert",
    "body": "警告类文案",
    "level": "warning",
    "className": "mb-1"
  },
  {
    "type": "alert",
    "title": "警告类标题",
    "body": "警告类文案",
    "level": "warning",
    "className": "mb-3"
  },
  {
    "type": "alert",
    "body": "危险类文案",
    "level": "danger",
    "className": "mb-1"
  },
  {
    "type": "alert",
    "title": "危险类标题",
    "body": "危险类文案",
    "level": "danger",
  },
]
```

## 图标

配置`"showIcon": true`后展示图标让信息更加醒目。可以通过`icon`属性自定义设置 icon 内容，如果`icon`属性为空，则根据`level`值添加默认 icon。

```schema: scope="body"
[
  {
    "type": "alert",
    "body": "提示类文案",
    "level": "info",
    "showIcon": true,
    "className": "mb-1"
  },
  {
    "type": "alert",
    "title": "提示类标题",
    "body": "提示类文案",
    "level": "info",
    "showIcon": true,
    "className": "mb-3"
  },
  {
    "type": "alert",
    "body": "成功类文案",
    "level": "success",
    "showIcon": true,
    "className": "mb-1"
  },
  {
    "type": "alert",
    "title": "成功类标题",
    "body": "成功类文案",
    "level": "success",
    "showIcon": true,
    "className": "mb-3"
  },
  {
    "type": "alert",
    "body": "警告类文案",
    "level": "warning",
    "showIcon": true,
    "className": "mb-1"
  },
  {
    "type": "alert",
    "title": "警告类标题",
    "body": "警告类文案",
    "level": "warning",
    "showIcon": true,
    "className": "mb-3"
  },
  {
    "type": "alert",
    "body": "危险类文案",
    "level": "danger",
    "showIcon": true,
    "className": "mb-1"
  },
  {
    "type": "alert",
    "title": "危险类标题",
    "body": "危险类文案",
    "level": "danger",
    "showIcon": true,
    "className": "mb-3"
  },
  {
    "type": "alert",
    "body": "自定义ICON文案",
    "showIcon": true,
    "icon": "info-circle",
    "className": "mb-1"
  },
  {
    "type": "alert",
    "title": "自定义ICON标题",
    "body": "自定义ICON文案",
    "showIcon": true,
    "icon": "fa fa-list"
  }
]
```

## level 支持表达式

> 1.6.4 及以上版本

修改下面例子的 status 值为 2 就能看到变化

```schema:
{
  "type": "page",
  "data": {
    "status": 1
  },
  "body": [
    {
      "type": "alert",
      "level": "${IFS(status===1, 'danger', status===2, 'warning')}",
      "body": "这是内容区"
    }
  ]
}
```

同时 icon 和 showIcon 也都支持表达式

## 显示关闭按钮

配置`"showCloseButton": true`实现显示关闭按钮。

```schema: scope="body"
[
  {
    "type": "alert",
    "body": "显示关闭按钮的提示",
    "level": "info",
    "showCloseButton": true,
    "showIcon": true,
    "className": "mb-2"
  },
  {
    "type": "alert",
    "title": "可关闭提示",
    "body": "显示关闭按钮的提示",
    "level": "success",
    "showCloseButton": true,
    "showIcon": true
  }
]
```

## 操作区域

> `3.6.0`及以上版本

配置`actions`属性，可以添加操作区域。

```schema: scope="body"
[
  {
    "type": "alert",
    "level": "success",
    "className": "mb-3",
    "showIcon": true,
    "showCloseButton": true,
    "title": "标题",
    "body": "创建成功",
    "actions": [
      {
        "type": "button",
        "label": "查看详情",
        "size": "xs",
        "level": "link",
        "style": {
          "position": "relative",
          "top": "25px",
          "left": "30px"
        }
      }
    ]
  },
  {
    "type": "alert",
    "level": "info",
    "showIcon": true,
    "showCloseButton": true,
    "body": "创建成功",
    "actions": {
      "type": "flex",
      "justify": "flex-start",
      "alignItems": "flex-start",
      "direction": "column",
      "style": {"padding": "6px"},
      "items": [
        {
          "type": "button",
          "label": "详情",
          "size": "xs",
          "level": "primary",
          "style": {
            "marginBottom": "5px"
          }
        },
        {
          "type": "button",
          "label": "关闭",
          "size": "xs",
          "level": "danger"
        }
      ]
    }
  }
]
```

## 属性表

| 属性名               | 类型                                      | 默认值    | 说明                                                     | 版本 |
| -------------------- | ----------------------------------------- | --------- | -------------------------------------------------------- | --- |
| type                 | `string`                                  | `"alert"` | 指定为 alert 渲染器                                      |
| title                | `string`                                  |           | alert标题                                                |
| className            | `string`                                  |           | 外层 Dom 的类名                                          |
| level                | `string`                                  | `info`    | 级别，可以是：`info`、`success`、`warning` 或者 `danger` |
| body                 | [`SchemaNode[] \| SchemaNode`](../../docs/types/schemanode) |           | 显示内容                                                 |
| showCloseButton      | `boolean`                                 | `false`   | 是否显示关闭按钮                                         |
| closeButtonClassName | `string`                                  |           | 关闭按钮的 CSS 类名                                      |
| showIcon             | `boolean`                                 | `false`   | 是否显示 icon                                            |
| icon                 | `string`                                  |           | 自定义 icon                                              |
| iconClassName        | `string`                                  |           | icon 的 CSS 类名                                         |
| actions        | [`SchemaNode[] \| SchemaNode`](../../docs/types/schemanode)               |           | 操作区域                                         | `3.6.0` |

---

### Zh CN Components Amis (`docs/zh-CN/components/amis.md`)

---
title: AMIS 渲染器
description:
type: 0
group: ⚙ 组件
menuName: AMIS 渲染器
icon:
order: 28
---

用于渲染数据中的 amis 配置

## 基本使用

只需要设置 schema 或 name，值可以是 JSON 对象或字符串的 JSON

```schema: scope="body"
{
  "type": "amis",
  "schema": {
    "type": "tpl",
    "tpl": "amis render"
  }
}
```

## 通过 name 绑定动态数据

可以用在表单或 CRUD 中，下面示例演示了编辑后实时渲染的效果，因为使用了相同 的 name

```schema: scope="body"
{
    "type": "form",
    "api": "/api/mock2/form/saveForm",
    "title": "实时测试 amis 渲染效果",
    "body": [
        {
            "type": "group",
            "body": [
                {
                    "type": "editor",
                    "name": "amis",
                    "language": "json",
                    "value": {
                      "label": "弹框",
                      "type": "button",
                      "actionType": "dialog",
                      "dialog": {
                        "title": "弹框",
                        "body": "这是个简单的弹框。"
                      }
                    }
                },
                {
                    "type": "amis",
                    "name": "amis"
                }
            ]
        }

    ]
}
```

## 向下传递 props

通过设置 props 向下传递，这个 props 会作为默认值

```schema: scope="body"
{
  "type": "amis",
  "props": {
    "tpl": "amis render"
  },
  "value": {
    "type": "tpl"
  }
}
```

## 属性表

| 属性名 | 类型     | 默认值   | 说明               |
| ------ | -------- | -------- | ------------------ |
| type   | `string` | `"amis"` | 指定为 amis 渲染器 |
| name   | `string` |          | 绑定上下文变量名   |
| props  | `object` |          | 向下传递的 props   |

---

### Zh CN Components Anchor Nav (`docs/zh-CN/components/anchor-nav.md`)

---
title: AnchorNav 锚点导航
description:
type: 0
group: ⚙ 组件
menuName: AnchorNav
icon:
order: 68
---

锚点导航容器组件。

## 基本用法

`6.1.0`及以上版本垂直方向支持配置子节点

```
/* Detailed source-code truncated for AI context efficiency. */
```

默认想要显示多少锚点导航配置多少个 `links` 成员即可。

## 水平导航

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 默认定位到某个区域

主要配置`active`属性来实现该效果，共有下面两种方法：

#### 配置 href 值

```
/* Detailed source-code truncated for AI context efficiency. */
```

#### 配置索引值

单个`link`上不要配置`href`属性，配置需要展示的`link`索引值，`0`代表第一个。

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 属性表

| 属性名             | 类型                              | 默认值                              | 说明                                                                       |
| ------------------ | --------------------------------- | ----------------------------------- | -------------------------------------------------------------------------- |
| type               | `string`                          | `"anchor-nav"`                      | 指定为 AnchorNav 渲染器                                                    |
| className          | `string`                          |                                     | 外层 Dom 的类名                                                            |
| linkClassName      | `string`                          |                                     | 导航 Dom 的类名                                                            |
| sectionClassName   | `string`                          |                                     | 锚点区域 Dom 的类名                                                        |
| links              | `Array`                           |                                     | links 内容                                                                 |
| direction          | `string`                          | `"vertical"`                        | 可以配置导航水平展示还是垂直展示。对应的配置项分别是：vertical、horizontal |
| active             | `string`                          |                                     | 需要定位的区域                                                             |
| links[x].title     | `string`                          |                                     | 区域 标题                                                                  |
| links[x].href      | `string`                          |                                     | 区域 标识                                                                  |
| links[x].body      | [SchemaNode](../types/schemanode) |                                     | 区域 内容区，`6.1.0`及以上版本垂直方向支持配置子节点                       |
| links[x].className | `string`                          | `"bg-white b-l b-r b-b wrapper-md"` | 区域成员 样式                                                              |

---

### Zh CN Components App (`docs/zh-CN/components/app.md`)

---
title: App 多页应用
description:
type: 0
group: ⚙ 组件
menuName: App 多页应用
icon:
order: 99
---

用于实现多页应用，适合于全屏模式，如果只是局部渲染请不要使用。

## 基本用法

类型定义为 `app`，通过 pages 定义页面，支持层级，支持内嵌 schema，或者 通过 schemaApi 远程拉取页面，完整用法请参考 [amis-admin](https://github.com/aisuda/amis-admin) 项目里的代码示例，需要修改 `env`：

```json
{
  "type": "app",
  "brandName": "应用名称",
  "pages": [
    {
      "label": "分组1",
      "children": [
        {
          "label": "父页面",
          "url": "/parent",
          "children": [
            {
              "label": "子页面",
              "url": "pageA",
              "schema": {
                "type": "page",
                "title": "Page A"
              }
            }
          ]
        }
      ]
    }
  ]
  ...
}
```

## 属性说明

- `type` 请配置成 `app`
- `api` 页面配置接口，如果你想远程拉取页面配置请配置。返回配置路径 `json>data>pages`，具体格式请参考 `pages` 属性。
- `brandName` 应用名称。
- `logo` 支持图片地址，或者 svg。
- `className` css 类名。
- `header` 顶部区域。
- `asideBefore` 页面菜单上前面区域。
- `asideAfter` 页面菜单下前面区域。
- `footer` 页面。
- `pages` `Array<页面配置>`具体的页面配置。
  通常为数组，数组第一层为分组，一般只需要配置 label 集合，如果你不想分组，直接不配置，真正的页面请在第二层开始配置，即第一层的 children 中。

  具体的页面配置也支持属性结构，每层有以下配置。

  - `label` 菜单名称。
  - `icon` 菜单图标，比如：fa fa-file.
  - `url` 页面路由路径，当路由命中该路径时，启用当前页面。当路径不是 `/` 打头时，会连接父级路径。比如：父级的路径为 `folder`，而此时配置 `pageA`, 那么当页面地址为 `/folder/pageA` 时才会命中此页面。当路径是 `/` 开头如： `/crud/list` 时，则不会拼接父级路径。另外还支持 `/crud/view/:id` 这类带参数的路由，页面中可以通过 `${params.id}` 取到此值。
  - `schema` 页面的配置，具体配置请前往 [Page 页面说明](./page)
  - `schemaApi` 如果想通过接口拉取，请配置。返回路径为 `json>data`。schema 和 schemaApi 只能二选一。
  - `link` 如果想配置个外部链接菜单，只需要配置 link 即可。
  - `redirect` 跳转，当命中当前页面时，跳转到目标页面。
  - `rewrite` 改成渲染其他路径的页面，这个方式页面地址不会发生修改。
  - `isDefaultPage` 当你需要自定义 404 页面的时候有用，不要出现多个这样的页面，因为只有第一个才会有用。
  - `visible` 有些页面可能不想出现在菜单中，可以配置成 `false`，另外带参数的路由无需配置，直接就是不可见的。
  - `className` 菜单类名。

## 事件表

当前组件会对外派发以下事件，可以通过`onEvent`来监听这些事件，并通过`actions`来配置执行的动作，在`actions`中可以通过`${事件参数名}`或`${event.data.[事件参数名]}`来获取事件产生的数据，详细请查看[事件动作](../../docs/concepts/event-action)。

| 事件名称 | 事件参数 | 说明                                                |
| -------- | -------- | --------------------------------------------------- |
| init     | -        | 组件实例被创建并插入 DOM 中时触发。2.4.1 及以上版本 |

## 动作表

| 动作名称 | 动作配置                   | 说明             |
| -------- | -------------------------- | ---------------- |
| reload   | -                          | 刷新（重新加载） |
| setValue | `value: object` 更新的数据 | 更新数据         |

---

### Zh CN Components Audio (`docs/zh-CN/components/audio.md`)

---
title: Audio 音频
description:
type: 0
group: ⚙ 组件
menuName: Audio 音频
icon:
order: 28
---

## 基本使用

```schema: scope="body"
{
    "type": "audio",
    "src": "https://amis.bj.bcebos.com/amis/2019-7/1562137295708/chicane-poppiholla-original-radio-edit%20(1).mp3"
}
```

## 属性表

| 属性名    | 类型      | 默认值                                           | 说明                                    |
| --------- | --------- | ------------------------------------------------ | --------------------------------------- |
| type      | `string`  | `"audio"`                                        | 指定为 audio 渲染器                     |
| className | `string`  |                                                  | 外层 Dom 的类名                         |
| inline    | `boolean` | true                                             | 是否是内联模式                          |
| src       | `string`  |                                                  | 音频地址                                |
| loop      | `boolean` | false                                            | 是否循环播放                            |
| autoPlay  | `boolean` | false                                            | 是否自动播放                            |
| rates     | `array`   | `[]`                                             | 可配置音频播放倍速如：`[1.0, 1.5, 2.0]` |
| controls  | `array`   | `['rates', 'play', 'time', 'process', 'volume']` | 内部模块定制化                          |

---

### Zh CN Components Avatar (`docs/zh-CN/components/avatar.md`)

---
title: Avatar 头像
description:
type: 0
group: ⚙ 组件
menuName: Avatar 头像
icon:
order: 27
---

用来显示用户头像

## 基本使用

```schema: scope="body"
{
  "type": "avatar",
  "src": "https://suda.cdn.bcebos.com/amis/images/alice-macaw.jpg"
}
```

## 文字

```schema: scope="body"
{
  "type": "avatar",
  "text": "AM"
}
```

## 图标

通过 icon 设置图标

```schema: scope="body"
{
  "type": "avatar",
  "icon": "fa fa-user"
}
```

> 如果同时存在 src、text 和 icon，会优先用 src、接着 text、最后 icon

## 动态图片或文字

src、text 都支持变量，可以从上下文中动态获取图片或文字，下面的例子中：

- 第一个获取到了，显示正常
- 第二个没获取到，因此降级为显示 icon
- 第三个图片没获取到，由于 text 优先级比 icon 高，所以显示 text

```schema
{
  "data": {
    "myAvatar": "https://suda.cdn.bcebos.com/amis/images/alice-macaw.jpg"
  },
  "type": "page",
  "body": [
    {
      "type": "avatar",
      "icon": "fa fa-user",
      "src": "$myAvatar"
    },
    {
      "type": "avatar",
      "icon": "fa fa-user",
      "src": "$other"
    },
    {
      "type": "avatar",
      "src": "$other",
      "icon": "fa fa-user",
      "text": "avatar"
    }
  ]
}
```

## 方形和圆角形

可以通过 shape 改成方形或圆角形

```schema: scope="body"
[
  {
    "type": "avatar",
    "shape": "square",
    "text": "AM"
  },
  {
    "type": "avatar",
    "shape": "rounded",
    "text": "AM",
    "style": {
      "marginLeft": "10px"
    }
  }
]

```

## 大小

通过 size 可以控制头像的大小

```schema: scope="body"
[
  {
    "type": "avatar",
    "size": 'large',
    "icon": "fa fa-user"
  },
  {
    "type": "avatar",
    "size": 'default',
    "icon": "fa fa-user"
  },
  {
    "type": "avatar",
    "size": 'small',
    "icon": "fa fa-user"
  },
  {
    "type": "avatar",
    "size": 60,
    "src": "https://suda.cdn.bcebos.com/amis/images/alice-macaw.jpg"
  },
  {
    "type": "avatar",
    "src": "https://suda.cdn.bcebos.com/amis/images/alice-macaw.jpg"
  },
  {
    "type": "avatar",
    "size": 20,
    "src": "https://suda.cdn.bcebos.com/amis/images/alice-macaw.jpg"
  },
]

```

## 控制字符类型距离左右两侧边界单位像素

通过 gap 可以控制字符类型距离左右两侧边界单位像素

```schema: scope="body"
[
  {
    "type": "avatar",
    "text": 'ejson',
    "gap": 2
  },
  {
    "type": "avatar",
    "text": "ejson",
    "gap": 7
  }
]

```

## 图片拉伸方式

通过 `fit` 可以控制图片拉伸方式，默认是 `'cover'`

```schema: scope="body"
[
  {
    "type": "avatar",
    "fit": "cover",
    "src": "https://suda.cdn.bcebos.com/images/amis/plumeria.jpeg"
  },
  {
    "type": "avatar",
    "fit": "fill",
    "src": "https://suda.cdn.bcebos.com/images/amis/plumeria.jpeg"
  },
  {
    "type": "avatar",
    "fit": "contain",
    "src": "https://suda.cdn.bcebos.com/images/amis/plumeria.jpeg"
  },
  {
    "type": "avatar",
    "fit": "none",
    "src": "https://suda.cdn.bcebos.com/images/amis/plumeria.jpeg"
  },
    {
    "type": "avatar",
    "fit": "scale-down",
    "src": "https://suda.cdn.bcebos.com/images/amis/plumeria.jpeg"
  }
]
```

## 控制图片是否允许拖动

通过 draggable 可以控制图片是否允许拖动

```schema: scope="body"
[
  {
    "type": "avatar",
    "fit": "cover",
    "src": "https://suda.cdn.bcebos.com/images/amis/plumeria.jpeg",
    "draggable": false
  },
    {
    "type": "avatar",
    "fit": "cover",
    "src": "https://suda.cdn.bcebos.com/images/amis/plumeria.jpeg",
    "draggable": true
  }
]
```

## 图片加载失败后，通过 onError 控制是否进行 text、icon 置换

> 如果同时存在 text 和 icon，会优先用 text、接着 icon

```schema: scope="body"
{
  "type": "avatar",
  "src": "empty",
  "text": "avatar",
  "onError": "return true;"
},
```

## 样式

可以通过 style 来控制背景及文字颜色

```schema: scope="body"
{
  "type": "avatar",
  "text": "AM",
  "style": {
    "background": "#DB3E35",
    "color": "#FFFFFF"
  }
}
```

## 属性表

| 属性名        | 类型                                                               | 默认值         | 说明                                                                                                                                                                                                                                                                                                                                 |
| ------------- | ------------------------------------------------------------------ | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| className     | `string`                                                           |                | 外层 dom 的类名                                                                                                                                                                                                                                                                                                                      |
| style         | `object`                                                           |                | 外层 dom 的样式                                                                                                                                                                                                                                                                                                                      |
| fit           | `'contain'` \| `'cover'` \| `'fill'` \| `'none'` \| `'scale-down'` | `'cover'`      | 具体细节可以参考 MDN [文档](https://developer.mozilla.org/zh-CN/docs/Web/CSS/object-fit)                                                                                                                                                                                                                                             |
| src           | `string`                                                           |                | 图片地址                                                                                                                                                                                                                                                                                                                             |
| defaultAvatar | `string`                                                           |                | 占位图                                                                                                                                                                                                                                                                                                                               |
| text          | `string`                                                           |                | 文字                                                                                                                                                                                                                                                                                                                                 |
| icon          | `string`                                                           | `'fa fa-user'` | 图标                                                                                                                                                                                                                                                                                                                                 |
| shape         | `'circle'` \| `'square'` \| `'rounded'`                            | `'circle'`     | 形状，有三种 `'circle'` （圆形）、`'square'`（正方形）、`'rounded'`（圆角）                                                                                                                                                                                                                                                          |
| size          | `number` \| `'default'` \| `'normal'` \| `'small'`                 | `'default'`    | `'default' \| 'normal' \| 'small'`三种字符串类型代表不同大小（分别是 48、40、32），也可以直接数字表示                                                                                                                                                                                                                                |
| gap           | `number`                                                           | 4              | 控制字符类型距离左右两侧边界单位像素                                                                                                                                                                                                                                                                                                 |
| alt           | `number`                                                           |                | 图像无法显示时的替代文本                                                                                                                                                                                                                                                                                                             |
| draggable     | `boolean`                                                          |                | 图片是否允许拖动                                                                                                                                                                                                                                                                                                                     |
| crossOrigin   | `'anonymous'` \| `'use-credentials'` \| `''`                       |                | 图片的 `CORS` 属性设置                                                                                                                                                                                                                                                                                                               |
| onError       | `string`                                                           |                | 图片加载失败的字符串，这个字符串是一个 New Function 内部执行的字符串，参数是 event（使用 event.nativeEvent 获取原生 dom 事件），这个字符串需要返回 boolean 值。设置 `"return ture;"` 会在图片加载失败后，使用 `text` 或者 `icon` 代表的信息来进行替换。目前图片加载失败默认是不进行置换。注意：图片加载失败，不包括$获取数据为空情况 |

## 事件表

> 6.1.0 及以上版本

当前组件会对外派发以下事件，可以通过`onEvent`来监听这些事件，并通过`actions`来配置执行的动作，在`actions`中可以通过`${事件参数名}`或`${event.data.[事件参数名]}`来获取事件产生的数据，详细查看[事件动作](../../docs/concepts/event-action)。

| 事件名称   | 事件参数 | 说明           |
| ---------- | -------- | -------------- |
| click      | -        | 点击时触发     |
| mouseenter | -        | 鼠标移入时触发 |
| mouseleave | -        | 鼠标移出时触发 |

### click

鼠标点击。可以尝试通过`${event.context.nativeEvent}`获取鼠标事件对象。

```schema: scope="body"
{
  "type": "avatar",
  "onEvent": {
    "click": {
      "actions": [
        {
          "actionType": "toast",
          "args": {
            "msgType": "info",
            "msg": "${event.context.nativeEvent.type}"
          }
        }
      ]
    }
  }
}
```

### mouseenter

鼠标移入。可以尝试通过`${event.context.nativeEvent}`获取鼠标事件对象。

```schema: scope="body"
{
  "type": "avatar",
  "onEvent": {
    "mouseenter": {
      "actions": [
        {
          "actionType": "toast",
          "args": {
            "msgType": "info",
            "msg": "${event.context.nativeEvent.type}"
          }
        }
      ]
    }
  }
}
```

### mouseleave

鼠标移出。可以尝试通过`${event.context.nativeEvent}`获取鼠标事件对象。

```schema: scope="body"
{
  "type": "avatar",
  "onEvent": {
    "mouseleave": {
      "actions": [
        {
          "actionType": "toast",
          "args": {
            "msgType": "info",
            "msg": "${event.context.nativeEvent.type}"
          }
        }
      ]
    }
  }
}
```

---

### Zh CN Components Badge (`docs/zh-CN/components/badge.md`)

---
title: Badge 角标
description:
type: 0
group: ⚙ 组件
menuName: Badge
icon:
order: 30
---

## 基本用法

部分组件可以设置 `badge` 属性来显示角标。

> 1.2.2 及之前版本只支持头像组件
>
> 1.2.3 开始支持按钮、链接、模板组件。

```schema: scope="body"
[
  {
    "type": "avatar",
    "badge": {
      "mode": "text",
      "text": 10
    }
  },
  {
    "type": "divider"
  },
  {
    "type": "action",
    "label": "按钮",
    "badge": {
      "mode": "text",
      "text": 15
    }
  },
  {
    "type": "divider"
  },
  {
    "type": "link",
    "href": "https://www.baidu.com",
    "body": "百度一下，你就知道",
    "badge": {
      "position": "top-right"
    }
  },
  {
    "type": "divider"
  },
  {
    "type": "tpl",
    "tpl": "Hello ${text}",
    "badge": {
      "mode": "text",
      "text": 25
    }
  },
  {
    "type": "divider"
  },
  {
    "type": "icon",
    "icon": "cloud",
    "className": "text-info text-xl",
    "badge": {
      "position": "top-left"
    }
  },
  {
    "type": "divider"
  },
  {
    "type": "action",
    "label": "按钮",
    "badge": {
      "mode": "ribbon",
      "text": "HOT"
    }
  },
]
```

## 显示文字或数值

设置 `mode` 为 `text`，通过 `text` 属性来显示文字或数字，数值为零的时候将不显示。

```schema: scope="body"
[
  {
    "type": "avatar",
    "badge": {
      "mode": "text",
      "text": 10
    }
  },
  {
    "type": "avatar",
    "className": "m-l",
    "badge": {
      "mode": "text",
      "text": 0
    }
  },
  {
    "type": "avatar",
    "className": "m-l",
    "badge": {
      "mode": "text",
      "text": "new"
    }
  }
]
```

## 显示位置

通过 `position` 来控制角标显示位置，默认 `top-right`，还可以设置为 `top-left`、`bottom-left`、`bottom-right`。

```schema: scope="body"
[
  {
    "type": "avatar",
    "badge": {
      "position": "top-left"
    }
  },
  {
    "type": "avatar",
    "className": "m-l",
    "badge": {
      "position": "bottom-left"
    }
  },
  {
    "type": "avatar",
    "className": "m-l",
    "badge": {
      "position": "bottom-right"
    }
  }
]
```

通过 `offset` 来控制角标显示位置，offset 相对于 position 位置进行水平、垂直偏移。offset 在 mode=ribbon 下设置无效。

```schema: scope="body"
[
  {
    "type": "avatar",
    "badge": {
      "offset": [10, 10]
    }
  }
]
```

## 动态数字

`text` 可以取上下文变量。

```schema
{
  "data": {
    "myData": 10
  },
  "type": "page",
  "body": [
    {
      "type": "avatar",
      "badge": {
        "mode": "text",
        "visibleOn": "this.myData > 1",
        "text": "${myData}"
      }
    }
  ]
}
```

## 设置封顶值

通过 `overflowCount` 可以设置封顶值。超过 overflowCount 的会显示为 ${overflowCount}+，默认的 overflowCount 为 99

```schema
{
  "type": "page",
  "body": [
    {
      "type": "avatar",
      "badge": {
        "mode": "text",
        "text": 10,
        "overflowCount": 9
      }
    }
  ]
}
```

## 动态控制是否显示角标

角标可以直接写表达式来判断是否显示

```schema
{
  "data": {
    "myData": 10
  },
  "type": "page",
  "body": [
    {
      "type": "avatar",
      "badge": "this.myData > 1"
    },
    {
      "type": "avatar",
      "className": "m-l",
      "badge": "this.myData > 10"
    }
  ]
}
```

还可以通过 `visibleOn` 表达式来动态控制，这样还能设置其他属性

```schema
{
  "data": {
    "myData": 10
  },
  "type": "page",
  "body": [
    {
      "type": "avatar",
      "badge": {
        "visibleOn": "this.myData > 1"
      }
    },
    {
      "type": "avatar",
      "className": "m-l",
      "badge": {
        "visibleOn": "this.myData > 10"
      }
    }
  ]
}
```

## 设置大小

通过 `size` 来控制大小

```schema: scope="body"
[
  {
    "type": "avatar",
    "badge": {
      "mode": "text",
      "text": 10,
      "size": 20
    }
  },
  {
    "type": "avatar",
    "className": "m-l",
    "badge": {
      "mode": "text",
      "text": 10,
      "size": 12
    }
  },
  {
    "type": "avatar",
    "className": "m-l",
    "badge": {
      "size": 12
    }
  },
  {
    "type": "avatar",
    "className": "m-l",
    "badge": {
      "size": 4
    }
  }
]
```

## 设置角标级别

通过 `level` 来设置角标级别，改变角标背景颜色

```schema: scope="body"
[
  {
    "type": "avatar",
    "badge": {
      "mode": "text",
      "text": 10,
      "size": 20,
      "level": "success"
    }
  },
]
```

## 是否显示动画

在默认点状态下，可以通过设置 `animation` 属性来控制是否显示动画

```schema: scope="body"
[
  {
    "type": "avatar",
    "badge": {
      "animation": true
    }
  }
]
```

## 自定义样式

通过 `style` 来控制展现样式，比如背景及文字的颜色

```schema: scope="body"
[
  {
    "type": "avatar",
    "badge": {
      "mode": "text",
      "text": 10,
      "style": {
        "background": "#46C93A"
      }
    }
  },
  {
    "type": "avatar",
    "className": "m-l",
    "badge": {
      "mode": "text",
      "text": 10,
      "style": {
        "background": "#1A5CFF"
      }
    }
  }
]
```

## 属性表

| 属性名        | 类型                                        | 默认值    | 说明                                                                   |
| ------------- | ------------------------------------------- | --------- | ---------------------------------------------------------------------- |
| mode          | `string`                                    | dot       | 角标类型，可以是 dot/text/ribbon                                       |
| text          | `string`\|`number`                          |           | 角标文案，支持字符串和数字，在 mode='dot'下设置无效                    |
| size          | `number`                                    |           | 角标大小                                                               |
| level         | `string`                                    |           | 角标级别, 可以是 info/success/warning/danger, 设置之后角标背景颜色不同 |
| overflowCount | `number`                                    | 99        | 设置封顶的数字值                                                       |
| position      | `string`                                    | top-right | 角标位置， 可以是 top-right/top-left/bottom-right/bottom-left          |
| offset        | `number[top, left]`                         | [0, 0]    | 角标位置，offset 相对于 position 位置进行水平、垂直偏移                |
| className     | `string`                                    |           | 外层 dom 的类名                                                        |
| animation     | `boolean`                                   |           | 角标是否显示动画                                                       |
| style         | `object`                                    |           | 角标的自定义样式                                                       |
| visibleOn     | [表达式](../../../docs/concepts/expression) |           | 控制角标的显示隐藏                                                     |

---

### Zh CN Components Barcode (`docs/zh-CN/components/barcode.md`)

---
title: BarCode 条形码
description:
type: 0
group: ⚙ 组件
menuName: BarCode 条形码
icon:
order: 62
---

## 基本用法

```schema: scope="body"
{
    "type": "barcode",
    "value": "amis"
}
```

## 条形码配置

通过 options 属性配置，具体请参考[这里](https://github.com/lindell/JsBarcode/wiki/Options)，比如

```schema: scope="body"
{
    "type": "barcode",
    "value": "123",
    "options": {
      "format": "pharmacode",
      "lineColor": "#0aa",
      "width": "4",
      "height": "40",
    }
}
```

## 属性表

| 属性名    | 类型     | 默认值 | 说明                           |
| --------- | -------- | ------ | ------------------------------ |
| className | `string` |        | 外层 CSS 类名                  |
| value     | `string` |        | 显示的颜色值                   |
| name      | `string` |        | 在其他组件中，时，用作变量映射 |

---

### Zh CN Components Breadcrumb (`docs/zh-CN/components/breadcrumb.md`)

---
title: Breadcrumb 面包屑
description:
type: 0
group: ⚙ 组件
menuName: Breadcrumb
icon:
order: 30
---

## 基本用法

```schema: scope="body"
{
  "type": "breadcrumb",
  "items": [
    {
      "label": "首页",
      "href": "https://baidu.gitee.com/",
      "icon": "fa fa-home"
    },

    {
      "label": "上级页面"
    },

    {
      "label": "当前页面"
    }
  ]
}
```

## 动态数据

可以配置 source 来获取上下文中的动态数据，结合 [service](service) 来实现动态生成。

```schema
{
  "type": "page",
  "data": {
    "breadcrumb": [
      {
        "label": "首页",
        "href": "https://baidu.gitee.com/"
      },

      {
        "label": "上级页面"
      },

      {
        "label": "当前页面"
      }
    ]
  },
  "body": {
    "type": "breadcrumb",
    "source": "${breadcrumb}"
  }
}
```

## 分隔符

```schema: scope="body"
{
  "type": "breadcrumb",
  "separator": ">",
  "separatorClassName": "text-black",
  "items": [
    {
      "href": "https://baidu.gitee.com/",
      "icon": "fa fa-home"
    },

    {
      "label": "上级页面"
    },

    {
      "label": "当前页面"
    }
  ]
}
```

## 下拉菜单

```schema: scope="body"
{
  "type": "breadcrumb",
  "separator": ">",
  "separatorClassName": "text-black",
  "items": [
    {
      "label": "首页",
      "href": "https://baidu.gitee.com/",
      "icon": "fa fa-home"
    },

    {
      "label": "上级页面",
      "dropdown": [
        {
          "label": "选项一",
          "href": "https://baidu.gitee.com/",
        },
        {
          "label": "选项二"
        }
      ]
    },
    {
      "label": "当前页面"
    }
  ]
}
```

## 最大展示长度

```schema: scope="body"
{
  "type": "breadcrumb",
  "separator": ">",
  "separatorClassName": "text-black",
  "labelMaxLength": 16,
  "tooltipPosition": "top",
  "items": [
    {
      "href": "https://baidu.gitee.com/",
      "icon": "fa fa-home"
    },

    {
      "label": "上级页面上级页面上级页面上级页面上级页面"
    },

    {
      "label": "当前页面"
    }
  ]
}
```

## 属性表

| 属性名              | 类型                             | 默认值         | 说明                                                  |
| ------------------ | -------------------------------- | ------------- | ---------------------------------------------------- |
| className          | `string`                         |               | 外层类名                                              |
| itemClassName      | `string`                         |               | 导航项类名                                             |
| separatorClassName | `string`                         |               | 分割符类名                                             |
| dropdownClassName  | `string`                         |               | 下拉菜单类名                                           |
| dropdownItemClassName | `string`                      |               | 下拉菜单项类名                                         |
| separator          | `string`                         |               | 分隔符                                                |
| labelMaxLength     | `number`                         | 16            | 最大展示长度                                           |
| tooltipPosition    | `top \| bottom \| left \| right` | `top`         | 浮窗提示位置                                           |
| source             | `string`                         |               | 动态数据                                              |
| items[].label      | `string`                         |               | 文本                                                  |
| items[].href       | `string`                         |               | 链接                                                  |
| items[].icon       | `string`                         |               | [图标](icon)                                          |
| items[].dropdown   | `dropdown[]`                     |               | 下拉菜单，dropdown[]的每个对象都包含label、href、icon属性  |

---

### Zh CN Components Button Group (`docs/zh-CN/components/button-group.md`)

---
title: ButtonGroup 按钮组
description:
type: 0
group: ⚙ 组件
menuName: ButtonGroup
icon:
order: 30
---

## 基本用法

```schema: scope="body"
{
  "type": "button-group",
  "buttons": [
    {
      "type": "button",
      "label": "Button",
      "actionType": "dialog",
      "dialog": {
        "confirmMode": false,
        "title": "提示",
        "body": "对，你刚点击了！"
      }
    },

    {
      "type": "button",
      "actionType": "url",
      "url": "https://www.baidu.com",
      "blank": true,
      "label": "百度一下"
    },

    {
      "type": "button",
      "label": "普通按钮"
    }
  ]
}
```

## 垂直模式

配置`"vertical": true`，实现垂直模式

```schema: scope="body"
[
  {
    "type": "button-group",
    "vertical": true,
    "buttons": [
      {
        "type": "button",
        "label": "按钮1"
      },
      {
        "type": "button",
        "label": "按钮2"
      },
      {
        "type": "button",
        "label": "按钮3"
      }
    ]
  }
]
```

## 平铺模式

配置 `"tiled": true` 实现平铺模式

```schema: scope="body"
[
  {
    "type": "button-group",
    "tiled": true,
    "buttons": [
      {
        "type": "button",
        "label": "按钮1"
      },
      {
        "type": "button",
        "label": "按钮2"
      },
      {
        "type": "button",
        "label": "按钮3"
      }
    ]
  }
]
```

## 按钮主题样式

配置 `btnLevel` 统一设置按钮主题样式，注意 `buttons ` 或 `options` 中的`level`属性优先级高于`btnLevel`。配置 `btnActiveLevel` 为按钮设置激活态时的主题样式。

```schema: scope="body"
[
  {
    "type": "button-group",
    "btnLevel": "light",
    "btnActiveLevel": "warning",
    "buttons": [
      {
        "type": "button",
        "label": "按钮1"
      },
      {
        "type": "button",
        "label": "按钮2"
      },
      {
        "type": "button",
        "label": "按钮3",
        "level": "primary"
      }
    ]
  }
]
```

## 属性表

| 属性名         | 类型                                                                                                                | 默认值           | 说明                       |
| -------------- | ------------------------------------------------------------------------------------------------------------------- | ---------------- | -------------------------- |
| type           | `string`                                                                                                            | `"button-group"` | 指定为 button-group 渲染器 |
| vertical       | `boolean`                                                                                                           | `false`          | 是否使用垂直模式           |
| tiled          | `boolean`                                                                                                           | `false`          | 是否使用平铺模式           |
| btnLevel       | `'link' \| 'primary' \| 'secondary' \| 'info'\|'success' \| 'warning' \| 'danger' \| 'light'\| 'dark' \| 'default'` | `"default"`      | 按钮样式                   |
| btnActiveLevel | `'link' \| 'primary' \| 'secondary' \| 'info'\|'success' \| 'warning' \| 'danger' \| 'light'\| 'dark' \| 'default'` | `"default"`      | 选中按钮样式               |
| buttons        | `Array<Action>`                                                                                                     |                  | [按钮](./action)           |
| className      | `string`                                                                                                            |                  | 外层 Dom 的类名            |

---

### Zh CN Components Button (`docs/zh-CN/components/button.md`)

---
title: Button 按钮
description:
type: 0
group: ⚙ 组件
menuName: Button 按钮
icon:
order: 29
---

## 基本用法

```schema: scope="body"
{
  "label": "弹个框",
  "type": "button",
  "actionType": "dialog",
  "dialog": {
    "title": "弹框",
    "body": "这是个简单的弹框。"
  }
}
```

`button` 实际上是 `action` 的别名，更多用法见 [action](./action)

## 属性表

| 属性名           | 类型                                                                                                                             | 默认值  | 说明                                                  |
| ---------------- | -------------------------------------------------------------------------------------------------------------------------------- | ------- | ----------------------------------------------------- |
| className        | `string`                                                                                                                         |         | 指定添加 button 类名                                  |
| url              | `string`                                                                                                                         |         | 点击跳转的地址，指定此属性 button 的行为和 a 链接一致 |
| size             | `'xs' \| 'sm' \| 'md' \| 'lg' `                                                                                                  |         | 设置按钮大小                                          |
| actionType       | `'button' \| 'reset' \| 'submit'\| 'clear'\| 'url'`                                                                              | button  | 设置按钮类型                                          |
| level            | `'link' \| 'primary' \| 'enhance' \| 'secondary' \| 'info'\|'success' \| 'warning' \| 'danger' \| 'light'\| 'dark' \| 'default'` | default | 设置按钮样式                                          |
| tooltip          | `'string' \| 'TooltipObject'`                                                                                                    |         | 气泡提示内容                                          |
| tooltipPlacement | `'top' \| 'right' \| 'bottom' \| 'left' `                                                                                        | top     | 气泡框位置器                                          |
| tooltipTrigger   | `'hover' \| 'focus'`                                                                                                             |         | 触发 tooltip                                          |
| disabled         | `'boolean'`                                                                                                                      | false   | 按钮失效状态                                          |
| disabledTip      | `'string' \| 'TooltipObject'`                                                                                                    |         | 按钮失效状态下的提示                                  |
| block            | `'boolean'`                                                                                                                      | false   | 将按钮宽度调整为其父宽度的选项                        |
| loading          | `'boolean'`                                                                                                                      | false   | 显示按钮 loading 效果                                 |
| loadingOn        | `'string'`                                                                                                                       |         | 显示按钮 loading 表达式                               |

---

### Zh CN Components Calendar (`docs/zh-CN/components/calendar.md`)

---
title: Calendar 日历日程
description:
type: 0
group: ⚙ 组件
menuName: Calendar 日历日程
icon:
order: 36
---

## 基本用法

设置 `schedules` 属性

```schema: scope="body"
{
    "type": "calendar",
    "value": "1638288000",
    "schedules": [
      {
        "startTime": "2021-12-11 05:14:00",
        "endTime": "2021-12-11 06:14:00",
        "content": "这是一个日程1"
      },
      {
        "startTime": "2021-12-21 05:14:00",
        "endTime": "2021-12-22 05:14:00",
        "content": "这是一个日程2"
      }
    ]
}
```

## 自定义颜色

```schema: scope="body"
{
    "type": "calendar",
    "value": "1638288000",
    "schedules": [
      {
        "startTime": "2021-12-11 05:14:00",
        "endTime": "2021-12-11 06:14:00",
        "content": "这是一个日程1",
        "className": "bg-success"
      },
      {
        "startTime": "2021-12-21 05:14:00",
        "endTime": "2021-12-22 05:14:00",
        "content": "这是一个日程2",
        "className": "bg-info"
      }
    ]
}
```

## 自定义日程展示

```schema: scope="body"
{
    "type": "calendar",
    "value": "1638288000",
    "schedules": [
      {
        "startTime": "2021-12-11 05:14:00",
        "endTime": "2021-12-11 06:14:00",
        "content": "这是一个日程1"
      },
      {
        "startTime": "2021-12-21 05:14:00",
        "endTime": "2021-12-22 05:14:00",
        "content": "这是一个日程2"
      }
    ],
    "scheduleAction": {
      "actionType": "drawer",
      "drawer": {
        "title": "日程",
        "body": {
          "type": "table",
          "columns": [
            {
              "name": "time",
              "label": "时间"
            },
            {
              "name": "content",
              "label": "内容"
            }
          ],
          "data": "${scheduleData}"
        }
      }
    }
}
```

## 支持从数据源中获取日程

```schema
{
    "type": "page",
    "data": {
      "schedules": [
        {
          "startTime": "2021-12-11 05:14:00",
          "endTime": "2021-12-11 06:14:00",
          "content": "这是一个日程1"
        },
        {
          "startTime": "2021-12-21 05:14:00",
          "endTime": "2021-12-22 05:14:00",
          "content": "这是一个日程2"
        }
      ]
    },
    "body": [
      {
        "type": "calendar",
        "value": "1638288000",
        "schedules": "${schedules}"
      }
    ]
}
```

## 放大模式

```schema: scope="body"
{
    "type": "calendar",
    "value": "1638288000",
    "largeMode": true,
    "schedules": [
      {
        "startTime": "2021-12-10 23:59:59",
        "endTime": "2021-12-11 00:00:00",
        "content": "这是一个日程1"
      },
      {
        "startTime": "2021-12-12 00:00:00",
        "endTime": "2021-12-13 00:00:01",
        "content": "这是一个日程2"
      },
      {
        "startTime": "2021-12-20 05:14:00",
        "endTime": "2021-12-21 05:14:00",
        "content": "这是一个日程3"
      },
      {
        "startTime": "2021-12-21 05:14:00",
        "endTime": "2021-12-22 05:14:00",
        "content": "这是一个日程4"
      },
      {
        "startTime": "2021-12-22 02:14:00",
        "endTime": "2021-12-23 05:14:00",
        "content": "这是一个日程5"
      },
      {
        "startTime": "2021-12-22 02:14:00",
        "endTime": "2021-12-22 05:14:00",
        "content": "这是一个日程6"
      },
      {
        "startTime": "2021-12-22 02:14:00",
        "endTime": "2021-12-22 05:14:00",
        "content": "这是一个日程7"
      },
      {
        "startTime": "2021-12-25 12:00:00",
        "endTime": "2021-12-25 15:00:00",
        "content": "这是一个日程8"
      }
    ]
}
```

## 今日高亮样式自定义

> 2.1.1 及以上版本

```schema: scope="body"
{
    "type": "calendar",
    "value": "NOW()",
    "todayActiveStyle": {
      "backgroundColor": "#ef4444 !important",
      "color": "#f8f9fa",
      "border": "none",
      "borderRadius": "15px"
    },
    "schedules": [
      {
        "startTime": "2021-12-11 05:14:00",
        "endTime": "2021-12-11 06:14:00",
        "content": "这是一个日程1"
      },
      {
        "startTime": "2021-12-21 05:14:00",
        "endTime": "2021-12-22 05:14:00",
        "content": "这是一个日程2"
      }
    ]
}
```

## Calendar 属性表

| 属性名             | 类型                                                                                      | 默认值                                                                 | 说明                                                                                                                                                                                                                            |
| ------------------ | ----------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| type               | `string`                                                                                  | `"calendar"`                                                           | 指定为 calendar 渲染器                                                                                                                                                                                                          |
| schedules          | `Array<{startTime: string, endTime: string, content: any, className?: string}> \| string` |                                                                        | 日历中展示日程，可设置静态数据或从上下文中取数据，startTime 和 endTime 格式参考[文档](https://momentjs.com/docs/#/parsing/string/)，className 参考[背景色](https://baidu.gitee.io/amis/zh-CN/style/background/background-color) |
| scheduleClassNames | `Array<string>`                                                                           | `['bg-warning', 'bg-danger', 'bg-success', 'bg-info', 'bg-secondary']` | 日历中展示日程的颜色，参考[背景色](https://baidu.gitee.io/amis/zh-CN/style/background/background-color)                                                                                                                         |
| scheduleAction     | `SchemaNode`                                                                              |                                                                        | 自定义日程展示                                                                                                                                                                                                                  |
| largeMode          | `boolean`                                                                                 | `false`                                                                | 放大模式                                                                                                                                                                                                                        |
| todayActiveStyle   | `Record<string, any>`                                                                     |                                                                        | 今日激活时的自定义样式                                                                                                                                                                                                          |

## 事件表

当前组件会对外派发以下事件，可以通过`onEvent`来监听这些事件，并通过`actions`来配置执行的动作，在`actions`中可以通过`${事件参数名}`来获取事件产生的数据（`< 2.3.2 及以下版本 为 ${event.data.[事件参数名]}`），详细请查看[事件动作](../../docs/concepts/event-action)。

| 事件名称   | 事件参数                 | 说明               |
| ---------- | ------------------------ | ------------------ |
| change     | `value: string` 组件的值 | 时间值变化时触发   |
| click      | `value: string` 组件的值 | 点击日期时触发     |
| mouseenter | `value: string` 组件的值 | 鼠标移入日期时触发 |
| mouseleave | `value: string` 组件的值 | 鼠标移出日期时触发 |

## 动作表

当前组件对外暴露以下特性动作，其他组件可以通过指定`actionType: 动作名称`、`componentId: 该组件id`来触发这些动作，动作配置可以通过`args: {动作配置项名称: xxx}`来配置具体的参数，详细请查看[事件动作](../../docs/concepts/event-action#触发其他组件的动作)。

| 动作名称 | 动作配置                 | 说明                                             |
| -------- | ------------------------ | ------------------------------------------------ |
| clear    | -                        | 清空                                             |
| reset    | -                        | 将值重置为初始值。6.3.0 及以下版本为`resetValue` |
| setValue | `value: string` 更新的值 | 更新数据                                         |

---

### Zh CN Components Card (`docs/zh-CN/components/card.md`)

---
title: Card 卡片
description:
type: 0
group: ⚙ 组件
menuName: Card 卡片
icon:
order: 31
---

## 基本用法

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 打开链接

> 1.4.0 及以上版本

通过 `href` 属性可以设置点击卡片打开外部链接

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 设置头像文本

如果没有 avatar，还可以通过 `avatarText` 设置头像文本

```schema: scope="body"
{
    "type": "card",
    "href": "https://github.com/baidu/amis",
    "header": {
        "title": "标题",
        "subTitle": "副标题",
        "description": "这是一段描述",
        "avatarText": "AMIS"
    },
    "body": "这里是内容"
}
```

> 1.5.0 及以上版本

可以设置文本背景色，它会根据数据分配一个颜色，主要配合 `cards` 使用

```schema
{
  "type": "page",
  "data": {
    "items": [
      {
        "engine": "Trident",
        "browser": "Internet Explorer 4.0"
      },
      {
        "engine": "Chrome",
        "browser": "Chrome 44"
      },
      {
        "engine": "Gecko",
        "browser": "Firefox 1.0"
      },
      {
        "engine": "Presto",
        "browser": "Opera 10"
      },
      {
        "engine": "Webkie",
        "browser": "Safari 12"
      }
    ]
  },
  "body": {
    "type": "cards",
    "source": "$items",
    "card": {
      "header": {
        "avatarText": "${engine|substring:0:2|upperCase}",
        "avatarTextBackground": ["#FFB900", "#D83B01", "#B50E0E", "#E81123", "#B4009E", "#5C2D91", "#0078D7", "#00B4FF", "#008272"]
      },
      "body": [
        {
          "label": "Browser",
          "name": "browser"
        }
      ]
    }
  }
}
```

## 点击卡片的行为

> 1.4.0 及以上版本

通过设置 `itemAction` 可以设置整个卡片的点击行为

```schema: scope="body"
{
    "type": "card",
    "itemAction": {
      "type": "button",
      "actionType": "dialog",
      "dialog": {
        "title": "详情",
        "body": "当前描述"
      }
    },
    "header": {
        "title": "标题",
        "subTitle": "副标题",
        "description": "这是一段描述",
        "avatarClassName": "pull-left thumb-md avatar b-3x m-r",
        "avatar": "data:image/svg+xml,%3C%3Fxml version='1.0' standalone='no'%3F%3E%3C!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'%3E%3Csvg t='1631083237695' class='icon' viewBox='0 0 1024 1024' version='1.1' xmlns='http://www.w3.org/2000/svg' p-id='2420' xmlns:xlink='http://www.w3.org/1999/xlink' width='1024' height='1024'%3E%3Cdefs%3E%3Cstyle type='text/css'%3E%3C/style%3E%3C/defs%3E%3Cpath d='M959.872 128c0.032 0.032 0.096 0.064 0.128 0.128v767.776c-0.032 0.032-0.064 0.096-0.128 0.128H64.096c-0.032-0.032-0.096-0.064-0.128-0.128V128.128c0.032-0.032 0.064-0.096 0.128-0.128h895.776zM960 64H64C28.8 64 0 92.8 0 128v768c0 35.2 28.8 64 64 64h896c35.2 0 64-28.8 64-64V128c0-35.2-28.8-64-64-64z' p-id='2421' fill='%23bfbfbf'%3E%3C/path%3E%3Cpath d='M832 288c0 53.024-42.976 96-96 96s-96-42.976-96-96 42.976-96 96-96 96 42.976 96 96zM896 832H128V704l224-384 256 320h64l224-192z' p-id='2422' fill='%23bfbfbf'%3E%3C/path%3E%3C/svg%3E"
    },
    "body": "这里是内容"
}
```

注意它和前面的 `href` 配置冲突，如果设置了 `href` 这个将不会生效

## 设置多媒体卡片

> 1.5.0 及以上版本

通过设置 `media` 可以设置为多媒体卡片, 通过 `mediaPosition` 可以设置多媒体位置

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 设置标签卡片

> 1.5.0 及以上版本

```schema: scope="body"
{
    "type": "card",
    "header": {
      "title": "标题"
    },
    "body": "这里是内容这里是内容这里是内容这里是内容这里是内容这里是内容这里是内容这里是内容这里是内容这里是内容这里是内容这里是内容这里是内容",
    "secondary": "次要说明",
    "actions": [
      {
        "type": "button",
        "label": "操作",
        "actionType": "dialog",
        "className": "mr-4",
        "dialog": {
          "title": "操作",
          "body": "你正在编辑该卡片"
        }
      },
      {
        "type": "button",
        "label": "操作",
        "actionType": "dialog",
        "className": "mr-2.5",
        "dialog": {
          "title": "操作",
          "body": "你正在编辑该卡片"
        }
      },
      {
        "type": "dropdown-button",
        "level": "link",
        "icon": "fa fa-ellipsis-h",
        "className": "pr-1 flex",
        "hideCaret": true,
        "buttons": [
          {
            "type": "button",
            "label": "编辑",
            "actionType": "dialog",
            "dialog": {
              "title": "编辑",
              "body": "你正在编辑该卡片"
            }
          },
          {
            "type": "button",
            "label": "删除",
            "actionType": "dialog",
            "dialog": {
              "title": "提示",
              "body": "你删掉了该卡片"
            }
          }
        ]
      }
    ],
    "toolbar": [
      {
        "type": "tpl",
        "tpl": "标签",
        "className": "label label-warning"
      }
    ]
}
```

## 设置按钮卡片

> 1.5.0 及以上版本

按钮卡片一般以卡片形式展示当前卡片的执行语义，例如：创建卡片、添加卡片等场景。

```schema: scope="body"
{
  "type": "card",
  "className": "hover:shadow",
  "body": {
    "type": "wrapper",
    "className": "h-32 flex items-center justify-center",
    "body": [
      {
        "type": "wrapper",
        "size": "none",
        "className": "text-center",
        "body": {
          "type": "icon",
          "icon": "plus",
          "className": "text-2xl",
        }
      },
      {
        "type": "wrapper",
        "size": "none",
        "body": "点击会有弹框"
      }
    ]
  },
  "itemAction": {
    "type": "button",
    "actionType": "dialog",
    "dialog": {
      "title": "详情",
      "body": "当前描述"
    }
  }
}
```

## 设置文本卡片

> 1.5.0 及以上版本

```schema: scope="body"
{
  "type": "card",
  "header": {
    "className": "items-center",
    "title": "卡片标题"
  },
  "body": {
    "type": "wrapper",
    "size": "none",
    "body": {
      "type": "tabs",
      "tabs": [
        {
          "title": "标签1",
          "className": "p-0",
          "tab": [
            {
              "type": "card",
              "className": "border-0",
              "header": {
                "className": "p-0 pb-2",
                "title": "内容标题"
              },
              "body": "卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容",
              "bodyClassName": "p-0"
            },
            {
              "type": "card",
              "className": "border-0",
              "header": {
                "className": "p-0 pb-2",
                "title": "内容标题"
              },
              "body": "卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容",
              "bodyClassName": "p-0"
            }
          ]
        },
        {
          "title": "标签2",
          "className": "p-0",
          "tab": "卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容卡片内容"
        }
      ]
    }
  },
  "toolbar": [
    {
      "type": "button",
      "label": "操作",
      "actionType": "dialog",
      "dialog": {
        "title": "操作",
        "body": "你正在编辑该卡片"
      }
    }
  ]
}
```

## 设置单元格卡片

> 1.5.0 及以上版本

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 配置工具栏

> 1.5.0 及以上版本

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 属性表

| 属性名                        | 类型                                 | 默认值                              | 说明                                              |
| ----------------------------- | ------------------------------------ | ----------------------------------- | ------------------------------------------------- |
| type                          | `string`                             | `"card"`                            | 指定为 Card 渲染器                                |
| className                     | `string`                             |                                     | 外层 Dom 的类名                                   |
| href                          | [模板](../../docs/concepts/template) |                                     | 外部链接                                          |
| header                        | `Object`                             |                                     | Card 头部内容设置                                 |
| header.className              | `string`                             |                                     | 头部类名                                          |
| header.title                  | [模板](../../docs/concepts/template) |                                     | 标题                                              |
| header.titleClassName         | `string`                             |                                     | 标题类名                                          |
| header.subTitle               | [模板](../../docs/concepts/template) |                                     | 副标题                                            |
| header.subTitleClassName      | `string`                             |                                     | 副标题类名                                        |
| header.subTitlePlaceholder    | `string`                             |                                     | 副标题占位                                        |
| header.description            | [模板](../../docs/concepts/template) |                                     | 描述                                              |
| header.descriptionClassName   | `string`                             |                                     | 描述类名                                          |
| header.descriptionPlaceholder | `string`                             |                                     | 描述占位                                          |
| header.avatar                 | [模板](../../docs/concepts/template) |                                     | 图片                                              |
| header.avatarClassName        | `string`                             | `"pull-left thumb avatar b-3x m-r"` | 图片包括层类名                                    |
| header.imageClassName         | `string`                             |                                     | 图片类名                                          |
| header.avatarText             | [模板](../../docs/concepts/template) |                                     | 如果不配置图片，则会在图片处显示该文本            |
| header.avatarTextBackground   | `Array`                              |                                     | 设置文本背景色，它会根据数据分配一个颜色          |
| header.avatarTextClassName    | `string`                             |                                     | 图片文本类名                                      |
| header.highlight              | `boolean`                            | `false`                             | 是否显示激活样式                                  |
| header.highlightClassName     | `string`                             |                                     | 激活样式类名                                      |
| header.href                   | [模板](../../docs/concepts/template) |                                     | 点击卡片跳转的链接地址                            |
| header.blank                  | `boolean`                            | `true`                              | 是否新窗口打开                                    |
| body                          | `Array`                              |                                     | 内容容器，主要用来放置非表单项组件                |
| bodyClassName                 | `string`                             |                                     | 内容区域类名                                      |
| actions                       | Array<[Action](./action)>            |                                     | 配置按钮集合                                      |
| actionsCount                  | `number`                             | `4`                                 | 按钮集合每行个数                                  |
| itemAction                    | [Action](./action)                   |                                     | 点击卡片的行为                                    |
| media                         | `Object`                             |                                     | Card 多媒体部内容设置                             |
| media.type                    | `'image'\|'video'`                   |                                     | 多媒体类型                                        |
| media.url                     | `string`                             |                                     | 图片/视频链接                                     |
| media.position                | `'left'\|'right'\|'top'\|'bottom'`   | `'left'`                            | 多媒体位置                                        |
| media.className               | `string`                             | `"w-44 h-28"`                       | 多媒体类名                                        |
| media.isLive                  | `boolean`                            | `false`                             | 视频是否为直播                                    |
| media.autoPlay                | `boolean`                            | `false`                             | 视频是否自动播放                                  |
| media.poster                  | `string`                             | `false`                             | 视频封面                                          |
| secondary                     | [模板](../../docs/concepts/template) |                                     | 次要说明                                          |
| toolbar                       | Array<[Action](./action)>            |                                     | 工具栏按钮                                        |
| dragging                      | `boolean`                            | `false`                             | 是否显示拖拽图标                                  |
| selectable                    | `boolean`                            | `false`                             | 卡片是否可选                                      |
| checkable                     | `boolean`                            | `true`                              | 卡片选择按钮是否禁用                              |
| selected                      | `boolean`                            | `false`                             | 卡片选择按钮是否选中                              |
| hideCheckToggler              | `boolean`                            | `false`                             | 卡片选择按钮是否隐藏                              |
| multiple                      | `boolean`                            | `false`                             | 卡片是否为多选                                    |
| useCardLabel                  | `boolean`                            | `true`                              | 卡片内容区的表单项 label 是否使用 Card 内部的样式 |

---

### Zh CN Components Cards (`docs/zh-CN/components/cards.md`)

---
title: Cards 卡片组
description:
type: 0
group: ⚙ 组件
menuName: Cards 卡片组
icon:
order: 32
---

卡片展示，不支持配置初始化接口初始化数据域，所以需要搭配类似像`Service`这样的，具有配置接口初始化数据域功能的组件，或者手动进行数据域初始化，然后通过`source`属性，获取数据链中的数据，完成数据展示。

## 基本用法

这里我们使用手动初始数据域的方式，即配置`data`属性，进行数据域的初始化。

```
/* Detailed source-code truncated for AI context efficiency. */
```

或者你也可以使用 CRUD 的 [card 模式](./crud#cards-%E5%8D%A1%E7%89%87%E6%A8%A1%E5%BC%8F)



## 当 cards 在 crud 中且配置了批量操作按钮时可点选

如果配置了 `checkOnItemClick`，当用户点击卡片时就能选中这个卡片，而不是只能点击勾选框才能选中

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 瀑布流布局

设置 `"masonryLayout": true` 开启瀑布流布局模式，适合展示不同高度的卡片内容，比如图片列表、社交媒体流等场景。

> 瀑布流布局支持两种方式设置列数:
>
> 1. 通过 `columnsCount` 设置固定列数
> 2. 通过 `itemClassName` 设置响应式列数,如 `Grid-col--xs6 Grid-col--sm4 Grid-col--md3` 可以在不同屏幕尺寸下展现不同的列数

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 属性表

| 属性名           | 类型                                         | 默认值              | 说明                           |
| ---------------- | -------------------------------------------- | ------------------- | ------------------------------ |
| type             | `string`                                     |                     | `"cards"` 指定为卡片组。       |
| title            | [模板](../../docs/concepts/template)         |                     | 标题                           |
| source           | [数据映射](../../docs/concepts/data-mapping) | `${items}`          | 数据源, 获取当前数据域中的变量 |
| placeholder      | [模板](../../docs/concepts/template)         | '暂无数据'          | 当没数据的时候的文字提示       |
| className        | `string`                                     |                     | 外层 CSS 类名                  |
| headerClassName  | `string`                                     | `amis-grid-header`  | 顶部外层 CSS 类名              |
| footerClassName  | `string`                                     | `amis-grid-footer`  | 底部外层 CSS 类名              |
| itemClassName    | `string`                                     | `col-sm-4 col-md-3` | 卡片 CSS 类名                  |
| card             | [Card](./card)                               |                     | 配置卡片信息                   |
| selectable       | `boolean`                                    | `false`             | 卡片组是否可选                 |
| multiple         | `boolean`                                    | `true`              | 卡片组是否为多选               |
| checkOnItemClick | `boolean`                                    |                     | 点选卡片内容是否选中卡片       |

## 动作表

> 6.4.0 或更高版本

当前组件对外暴露以下特性动作，其他组件可以通过指定`actionType: 动作名称`、`componentId: 该组件id`来触发这些动作，动作配置可以通过`args: {动作配置项名称: xxx}`来配置具体的参数，详细请查看[事件动作](../../docs/concepts/event-action#触发其他组件的动作)。

| 动作名称        | 动作配置                                                                                                                                | 说明                 |
| --------------- | --------------------------------------------------------------------------------------------------------------------------------------- | -------------------- |
| select          | `args.index` 可选，指定行数，支持表达式 <br /> `args.condition` 可选，通过表达式指定更新哪些行，支持条件组合 index`                     | 设置列表的选中项     |
| selectAll       | -                                                                                                                                       | 设置列表全部项选中   |
| clearAll        | -                                                                                                                                       | 清空列表所有选中项   |
| initDrag        | -                                                                                                                                       | 开启列表拖拽排序功能 |
| cancelDrag      | -                                                                                                                                       | 放弃列表拖拽排序功能 |
| setValue        | `args.value`: object <br />`args.index` 可选，指定行数，支持表达式 <br /> `args.condition` 可选，通过表达式指定更新哪些行，支持条件组合 | 更新列表记录         |
| submitQuickEdit |                                                                                                                                         | 快速编辑数据提交     |

### select

- `args.index` 可选，指定行数，支持表达式
- `args.condition` 可选，通过表达式指定更新哪些行，支持条件组合

```schema: scope="body"
[
    {
    "type": "button-toolbar",
    "className": "m-b",
    "buttons": [
    {
        "name": "trigger1",
        "id": "trigger1",
        "type": "action",
        "label": "选中前两个",
        "onEvent": {
        "click": {
            "actions": [
            {
                "actionType": "select",
                "componentId": "cards-select",
                "args": {
                    "index": "0,1"
                }
            }
            ]
        }
        }
    }
    ]
},
{
    "type": "service",
    "api": "/api/mock2/sample?perPage=5",
    "body": [
    {
      "id": "cards-select",
      "type": "cards",
      "source": "$rows",
      "selectable": true,
      "multiple": true,
      "card": {
        "body": [
          {
            "label": "Engine",
            "name": "engine"
          },
          {
            "label": "Browser",
            "name": "browser"
          },
          {
            "name": "version",
            "label": "Version"
          }
        ]
      }
    }
  ]
}
]
```

### selectAll

```schema: scope="body"
[
    {
    "type": "button-toolbar",
    "className": "m-b",
    "buttons": [
    {
        "name": "trigger2",
        "id": "trigger2",
        "type": "action",
        "label": "设置列表全部项选中",
        "onEvent": {
        "click": {
            "actions": [
            {
                "actionType": "selectAll",
                "componentId": "cards-select",
                "description": "点击设置指定列表全部内容选中"
            }
            ]
        }
        }
    }
    ]
},
{
    "type": "service",
    "api": "/api/mock2/sample?perPage=10",
    "body": [
    {
        "id": "cards-select",
        "type": "cards",
        "source": "$rows",
        "selectable": true,
        "multiple": true,
        "card": {
          "body": [
            {
              "label": "Engine",
              "name": "engine"
            },
            {
              "label": "Browser",
              "name": "browser"
            },
            {
              "name": "version",
              "label": "Version"
            }
          ]
        }
    }
    ]
}
]
```

### clearAll

```schema: scope="body"
[
    {
    "type": "button-toolbar",
    "className": "m-b",
    "buttons": [
    {
        "name": "trigger3",
        "id": "trigger3",
        "type": "action",
        "label": "清空列表全部选中项",
        "onEvent": {
        "click": {
            "actions": [
            {
                "actionType": "clearAll",
                "componentId": "cards-select",
                "description": "点击设置指定列表全部选中项清空"
            }
            ]
        }
        }
    }
    ]
},
{
    "type": "service",
    "api": "/api/mock2/sample?perPage=10",
    "body": [
    {
        "id": "cards-select",
        "type": "cards",
        "source": "$rows",
        "selectable": true,
        "multiple": true,
        "card": {
          "body": [
            {
              "label": "Engine",
              "name": "engine"
            },
            {
              "label": "Browser",
              "name": "browser"
            },
            {
              "name": "version",
              "label": "Version"
            }
          ]
        }
    }
    ]
}
]
```

### initDrag & cancelDrag

```schema: scope="body"
[
    {
    "type": "button-toolbar",
    "className": "m-b",
    "buttons": [
    {
        "name": "trigger4",
        "id": "trigger4",
        "type": "action",
        "label": "开启列表行排序",
        "onEvent": {
        "click": {
            "actions": [
            {
                "actionType": "initDrag",
                "componentId": "cards-select",
                "description": "点击开启列表行排序功能"
            }
            ]
        }
        }
    },
    {
        "name": "trigger5",
        "id": "trigger5",
        "type": "action",
        "label": "取消列表行排序",
        "onEvent": {
        "click": {
            "actions": [
            {
                "actionType": "cancelDrag",
                "componentId": "cards-select",
                "description": "点击取消列表行排序功能"
            }
            ]
        }
        }
    }
    ]
},
{
    "type": "service",
    "api": "/api/mock2/sample?perPage=10",
    "body": [
    {
        "id": "cards-select",
        "type": "cards",
        "source": "$rows",
        "card": {
          "body": [
            {
              "label": "Engine",
              "name": "engine"
            },
            {
              "label": "Browser",
              "name": "browser"
            },
            {
              "name": "version",
              "label": "Version"
            }
          ]
        }
    }
    ]
}
]
```

### setValue

#### 更新列表记录

```
/* Detailed source-code truncated for AI context efficiency. */
```

#### 更新指定行记录

可以通过指定`index`或者`condition`来分别更新指定索引的行记录和指定满足条件（条件表达式或者 ConditionBuilder）的行记录，另外`replace`同样生效，即可以完全替换指定行记录，也可以对指定行记录做合并。

```
/* Detailed source-code truncated for AI context efficiency. */
```

---

### Zh CN Components Carousel (`docs/zh-CN/components/carousel.md`)

---
title: Carousel 轮播图
description:
type: 0
group: ⚙ 组件
menuName: Carousel 幻灯片
icon:
order: 33
---

## 基本用法

```schema: scope="body"
{
    "type": "carousel",
    "auto": false,
    "thumbMode": "cover",
    "animation": "slide",
    "height": 300,
    "options": [
        {
            "image": "https://internal-amis-res.cdn.bcebos.com/images/2019-12/1577157239810/da6376bf988c.png"
        },
        {
            "html": "<div style=\"width: 100%; height: 300px; background: #e3e3e3; text-align: center; line-height: 300px;\">carousel data</div>"
        },
        {
            "thumbMode": "contain",
            "image": "https://suda.cdn.bcebos.com/amis/images/alice-macaw.jpg"
        }
    ]
}
```

## 动态列表

轮播图组件目前没有获取数据的配置，因此需要依赖 `service` 来获取数据。

```schema: scope="body"
{
  "type": "page",
  "body": {
    "type": "service",
    "api": "/api/mock2/options/carousel",
    "body": {
      "type": "carousel",
      "name": "imageList"
    }
  }
}
```

目前数据关联是通过 name 的方式，因此 api 返回应该是类似这样的：

```
{
    status: 0,
    msg: '',
    data: {
        imageList: [{
            "image": "https://internal-amis-res.cdn.bcebos.com/images/2019-12/1577157239810/da6376bf988c.png"
        }]
    }
}
```

其中的 `imageList` 要和配置的 `name` 值对应。

## 点击图片打开外部链接

> 1.3.3 及以上版本

需要放回的字段中除了前面的 image，还有 href 属性

```schema: scope="body"
{
  "type": "page",
  "data": {
    "imageList": [
      {
        "image": "https://internal-amis-res.cdn.bcebos.com/images/2019-12/1577157239810/da6376bf988c.png",
        "href": "https://github.com/baidu/amis"
      }
    ]
  },
  "body": {
    "type": "carousel",
    "name": "imageList"
  }
}
```

## 自定义轮播图的展现

通过配置 `itemSchema` 可以自定义轮播图的展现，比如图片默认背景配置是 contain，可以改成 cover：

```
itemSchema: {
    type: 'tpl',
    tpl: '<div style="background-image: url("${image}"); background-size: cover; background-repeat: no-repeat; background-position: center center;" class="image ${imageClassName}"></div>'
}
```

## 多图展示

> `2.8.1` 及以上版本

```schema: scope="body"
{
    "type": "carousel",
    "auto": false,
    "thumbMode": "cover",
    "animation": "slide",
    "multiple": {count: 3},
    "interval": 1000,
    "duration": 5000,
    "height": 300,
    "options": [
        {
            "image": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,w_216,l_1,f_jpg,q_80"
        },
        {
            "image": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692942/d8e4992057f9.jpeg@s_0,w_216,l_1,f_jpg,q_80"
        },
        {
            "image": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693148/1314a2a3d3f6.jpeg@s_0,w_216,l_1,f_jpg,q_80"
        },
        {
            "image": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693379/8f2e79f82be0.jpeg@s_0,w_216,l_1,f_jpg,q_80"
        }
    ]
}
```

## 属性表

| 属性名                       | 类型                                                  | 默认值                 | 说明                                                    | 版本    |
| ---------------------------- | ----------------------------------------------------- | ---------------------- | ------------------------------------------------------- | ------- |
| type                         | `string`                                              | `"carousel"`           | 指定为 Carousel 渲染器                                  |
| className                    | `string`                                              | `"panel-default"`      | 外层 Dom 的类名                                         |
| options                      | `array`                                               | `[]`                   | 轮播面板数据                                            |
| options.image                | `string`                                              |                        | 图片链接                                                |
| options.href                 | `string`                                              |                        | 图片打开网址的链接                                      |
| options.imageClassName       | `string`                                              |                        | 图片类名                                                |
| options.title                | `string`                                              |                        | 图片标题                                                |
| options.titleClassName       | `string`                                              |                        | 图片标题类名                                            |
| options.description          | `string`                                              |                        | 图片描述                                                |
| options.descriptionClassName | `string`                                              |                        | 图片描述类名                                            |
| options.html                 | `string`                                              |                        | HTML 自定义，同[Tpl](./tpl)一致                         |
| itemSchema                   | `object`                                              |                        | 自定义`schema`来展示数据                                |
| auto                         | `boolean`                                             | `true`                 | 是否自动轮播                                            |
| interval                     | `string`                                              | `5s`                   | 切换动画间隔                                            |
| duration                     | `number`                                              | `500`                  | 切换动画时长（ms）                                      |
| width                        | `string`                                              | `auto`                 | 宽度                                                    |
| height                       | `string`                                              | `200px`                | 高度                                                    |
| controls                     | `array`                                               | `['dots', 'arrows']`   | 显示左右箭头、底部圆点索引                              |
| controlsTheme                | `string`                                              | `light`                | 左右箭头、底部圆点索引颜色，默认`light`，另有`dark`模式 |
| animation                    | `string`                                              | fade                   | 切换动画效果，默认`fade`，另有`slide`模式，`marquee`跑马灯模式               |
| thumbMode                    | `string`                                              | `"cover" \| "contain"` | 图片默认缩放模式                                        |
| multiple                     | `object`                                              | `{count: 1}`           | 多图展示，count 表示展示的数量                          | `2.8.1` |
| alwaysShowArrow              | `boolean`                                             | `false`                | 是否一直显示箭头，为 false 时鼠标 hover 才会显示        | `2.8.1` |
| icons                        | {prev: `SchemaCollection`; next: `SchemaCollection`;} |                        | 自定义箭头图标                                          | `2.8.1` |

## 事件表

当前组件会对外派发以下事件，可以通过`onEvent`来监听这些事件，并通过`actions`来配置执行的动作，在`actions`中可以通过`${事件参数名}`或`${event.data.[事件参数名]}`来获取事件产生的数据，详细请查看[事件动作](../../docs/concepts/event-action)。

| 事件名称 | 事件参数                                                                         | 说明             |
| -------- | -------------------------------------------------------------------------------- | ---------------- |
| change   | `activeIndex: number` 激活图片的索引 <br /> `prevIndex: number` 上一张图片的索引 | 轮播图切换时触发 |

### change

```schema: scope="body"
{
  "type": "carousel",
  "auto": false,
  "thumbMode": "cover",
  "animation": "slide",
  "height": 300,
  "options": [
    {
      "image": "https://internal-amis-res.cdn.bcebos.com/images/2019-12/1577157239810/da6376bf988c.png"
    },
    {
      "html": "<div style=\"width: 100%; height: 300px; background: #e3e3e3; text-align: center; line-height: 300px;\">carousel data</div>"
    },
    {
      "thumbMode": "contain",
      "image": "https://suda.cdn.bcebos.com/amis/images/alice-macaw.jpg"
    }
  ],
  "onEvent": {
    "change": {
      "actions": [
        {
          "actionType": "toast",
          "args": {
            "msg": "滚动至${activeIndex}"
          }
        }
      ]
    }
  }
}
```

## 动作表

当前组件对外暴露以下特性动作，其他组件可以通过指定`actionType: 动作名称`、`componentId: 该组件id`来触发这些动作，动作配置可以通过`args: {动作配置项名称: xxx}`来配置具体的参数，详细请查看[事件动作](../../docs/concepts/event-action#触发其他组件的动作)。

| 动作名称   | 动作配置                             | 说明       |
| ---------- | ------------------------------------ | ---------- |
| next       | -                                    | 下一张     |
| prev       | -                                    | 上一张     |
| goto-image | `activeIndex: number` 切换图片的索引 | 切换轮播图 |

### next

```schema: scope="body"
[
  {
    "type": "action",
    "label": "下一张",
    "className": "mr-3 mb-3",
    "onEvent": {
      "click": {
        "actions": [
          {
            "actionType": "next",
            "componentId": "carousel_001"
          }
        ]
      }
    }
  },
  {
    "type": "carousel",
    "id": "carousel_001",
    "auto": false,
    "thumbMode": "cover",
    "animation": "slide",
    "height": 300,
    "options": [
      {
        "image": "https://internal-amis-res.cdn.bcebos.com/images/2019-12/1577157239810/da6376bf988c.png"
      },
      {
        "html": "<div style=\"width: 100%; height: 300px; background: #e3e3e3; text-align: center; line-height: 300px;\">carousel data</div>"
      },
      {
        "thumbMode": "contain",
        "image": "https://suda.cdn.bcebos.com/amis/images/alice-macaw.jpg"
      }
    ]
  }
]
```

### prev

```schema: scope="body"
[
  {
    "type": "action",
    "label": "上一张",
    "className": "mr-3 mb-3",
    "onEvent": {
      "click": {
        "actions": [
          {
            "actionType": "prev",
            "componentId": "carousel_002"
          }
        ]
      }
    }
  },
  {
    "type": "carousel",
    "id": "carousel_002",
    "auto": false,
    "thumbMode": "cover",
    "animation": "slide",
    "height": 300,
    "options": [
      {
        "image": "https://internal-amis-res.cdn.bcebos.com/images/2019-12/1577157239810/da6376bf988c.png"
      },
      {
        "html": "<div style=\"width: 100%; height: 300px; background: #e3e3e3; text-align: center; line-height: 300px;\">carousel data</div>"
      },
      {
        "thumbMode": "contain",
        "image": "https://suda.cdn.bcebos.com/amis/images/alice-macaw.jpg"
      }
    ]
  }
]
```

### goto-image

```schema: scope="body"
[
  {
    "type": "action",
    "label": "滚动到第三张",
    "className": "mr-3 mb-3",
    "onEvent": {
      "click": {
        "actions": [
          {
            "actionType": "goto-image",
            "componentId": "carousel_003",
            "args": {
              "activeIndex": "${index}"
            }
          }
        ]
      }
    }
  },
  {
    "type": "carousel",
    "id": "carousel_003",
    "auto": false,
    "thumbMode": "cover",
    "animation": "slide",
    "height": 300,
    "options": [
      {
        "image": "https://internal-amis-res.cdn.bcebos.com/images/2019-12/1577157239810/da6376bf988c.png"
      },
      {
        "html": "<div style=\"width: 100%; height: 300px; background: #e3e3e3; text-align: center; line-height: 300px;\">carousel data</div>"
      },
      {
        "thumbMode": "contain",
        "image": "https://suda.cdn.bcebos.com/amis/images/alice-macaw.jpg"
      }
    ]
  }
]
```

---

### Zh CN Components Chart (`docs/zh-CN/components/chart.md`)

---
title: Chart 图表
description:
type: 0
group: ⚙ 组件
menuName: Chart 图标
icon:
order: 34
---

图表渲染器，采用 echarts 渲染，配置格式跟 echarts 相同，[echarts 配置文档](https://echarts.apache.org/zh/option.html#title)

## 基本用法

```schema: scope="body"
{
    "type": "chart",
    "api": "/api/mock2/chart/chart",
    "interval": 5000
}
```

api 返回支持两种格式，一种是直接返回完整 echarts 配置，数据包含在配置里，具体格式请参考后面的静态数据写法，另一种是返回纯数据，具体请参考动态数据写法。

## 静态数据

在 `config` 里填写完整的 echarts 配置，这里的数据是静态的。

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 动态数据

如果要实现动态数据，需要在 config 中做调整，比如将前面的例子改成如下写法

```schema: scope="body"
{
    "type": "chart",
    "api": "/api/mock2/chart/chartData",
    "config": {
        "xAxis": {
            "type": "category",
            "data": ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
        },
        "yAxis": {
            "type": "value"
        },
        "series": [{
            "data": "${line || []}",
            "type": "line"
        }]
    }
}
```

> Echarts 中有些配置不能为未定义，所以要使用变量，最好使用类似上面的 `${line || []}` 写法配置默认值，保证在数据加载完前渲染也不会报错

其中 api 返回内容是如下写法，可以看到通过[数据映射](../../docs/concepts/data-mapping)语法，我们可以将 api 放回结果中的 line 字段作为折线的数据。

```json
{
  "status": 0,
  "msg": "ok",
  "data": {
    "line": [65, 63, 10, 73, 42, 21]
  }
}
```

除了 `config` 中的 `data`，`config` 里的其它属性也都支持数据映射，还能支持数据映射中的各种过滤器。

### 使用上层数据接口

有时候数据是在上层获取的，比如通过 service 中返回了数据，这时需要通过 `trackExpression` 来指定跟踪什么数据，比如下面的例子，数据是从 service 获取的就需要配置 `trackExpression`。

> 如果`trackExpression` 追踪的数据是**对象数据**，可以使用[数据映射](../../docs/concepts/data-mapping)的`json`方法将数据序列化之后再比较，例如`"trackExpression": "${fieldToTrack|json}"`

```schema: scope="body"
{
    "type": "service",
    "api": "/api/mock2/chart/chartData",
    "interval": 3000,
    "body": [
        {
            "type": "chart",
            "trackExpression": "${line}",
            "config": {
                "xAxis": {
                    "type": "category",
                    "data": ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
                },
                "yAxis": {
                    "type": "value"
                },
                "series": [{
                    "data": "${line || []}",
                    "type": "line"
                }]
            }
        }
    ]
}

```

## 配置图表点击行为

可以通过配置`"clickAction": {}`，来指定图表节点的点击行为，支持 amis 的 [行为](./action)。

然后在配置的行为中可以通过 [数据链](../../docs/concepts/datascope-and-datachain) 获取到 [echarts 鼠标事件](https://echarts.apache.org/zh/api.html#events.%E9%BC%A0%E6%A0%87%E4%BA%8B%E4%BB%B6.click) 的值，例如下面例子中可以通过`${value|json}`获取到点击节点的`传入的数据值`

> 点击下面坐标中的节点查看效果！

```
/* Detailed source-code truncated for AI context efficiency. */
```

具体能拿到的参数请参考 [Echarts](https://echarts.apache.org/handbook/zh/concepts/event#%E9%BC%A0%E6%A0%87%E4%BA%8B%E4%BB%B6%E7%9A%84%E5%A4%84%E7%90%86) 的文档，官方定义如下

```typescript
type EventParams = {
  // 当前点击的图形元素所属的组件名称，
  // 其值如 'series'、'markLine'、'markPoint'、'timeLine' 等。
  componentType: string;
  // 系列类型。值可能为：'line'、'bar'、'pie' 等。当 componentType 为 'series' 时有意义。
  seriesType: string;
  // 系列在传入的 option.series 中的 index。当 componentType 为 'series' 时有意义。
  seriesIndex: number;
  // 系列名称。当 componentType 为 'series' 时有意义。
  seriesName: string;
  // 数据名，类目名
  name: string;
  // 数据在传入的 data 数组中的 index
  dataIndex: number;
  // 传入的原始数据项
  data: Object;
  // sankey、graph 等图表同时含有 nodeData 和 edgeData 两种 data，
  // dataType 的值会是 'node' 或者 'edge'，表示当前点击在 node 还是 edge 上。
  // 其他大部分图表中只有一种 data，dataType 无意义。
  dataType: string;
  // 传入的数据值
  value: number | Array;
  // 数据图形的颜色。当 componentType 为 'series' 时有意义。
  color: string;
};
```

## 远程拉取动态配置项

配置`api`，来远程拉取图标配置

```schema: scope="body"
{
    "type": "chart",
    "api": "/api/mock2/chart/chart1"
}
```

## 通过组件间联动，更新图表

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 对函数配置的特殊支持

ECharts 中有些配置项可以写函数，比如 formatter 和 sort，但在 JSON 里无法写函数，因此我们做了特殊支持，将看起来像函数的字符串转成了函数：

```schema: scope="body"
{
    "type": "chart",
    "config": {
        "legend": {
            "formatter": "function (name) { return 'Legend ' + name;}"
        },
        "dataset": {
            "source": [["type","2012","2013","2014","2015","2016"],["Forest",320,332,301,334,390],["Steppe",220,182,191,234,290],["Desert",150,232,201,154,190],["Wetland",98,77,101,99,40]]
        },
        "xAxis": {
            "type": "category",
            "axisTick": {
                "show": false
            }
        },
        "yAxis": {},
        "series": [{"type":"bar","seriesLayoutBy":"row"},{"type":"bar","seriesLayoutBy":"row"},{"type":"bar","seriesLayoutBy":"row"},{"type":"bar","seriesLayoutBy":"row"}]
    }
}
```

## 使用地图

从 amis 1.1.0 版本开始，ECharts 版本升级到 5.0.0，为了规避政策风险，在这个版本删除了之前的地图 geojson，如果需要这个功能需要手动引入。

方法是去 `https://github.com/apache/echarts/tree/master/test/data/map/js` 下载 `china.js` 和 `world.js`。

对于 npm 版本，直接 `import` 这两个文件就行。

对于 JS SDK 版本，需要先加入如下代码如下方式：

```javascript
window.echarts = amisRequire('echarts');
```

然后通过 script 标签引入这两个文件，或者用下面的新版方法

## 地图配置

> 2.4.1 及以上版本

新增了 `mapURL` 及 `mapName` 两个配置项

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 加载百度地图

配置 `loadBaiduMap` 后会加载百度地图，需要配置 `ak`

```schema: scope="body"
{
  "type": "chart",
  "loadBaiduMap": true,
  "ak": "LiZT5dVbGTsPI91tFGcOlSpe5FDehpf7",
  "config": {
    "bmap": {
      "center": [116.414, 39.915],
      "zoom": 14,
      "roam": true
    }
  }
}
```

## 动态处理 echart 配置

echarts 的 config 一般是静态配置的，支持简单的数据映射。如果你觉得还不够灵活可以通过自己手写逻辑代码来完成配置。

通过配置 dataFiler 来处理。

```schema: scope="body"
{
    "type": "chart",
    "data": {
        "line": [65, 63, 10, 73, 42, 21],
        "line2": [22, 33, 90, 20, 11, 33]
    },
    "config": {
        "xAxis": {
            "type": "category",
            "data": ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
        },
        "yAxis": {
            "type": "value"
        }
    },
    "dataFilter": "config.series = [];Object.keys(data).forEach(function(key) {config.series.push({data: data[key], type: 'line'})})"
}
```

## 属性表

| 属性名             | 类型                                         | 默认值    | 说明                                                                                                                                                                                     |
| ------------------ | -------------------------------------------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| type               | `string`                                     | `"chart"` | 指定为 chart 渲染器                                                                                                                                                                      |
| className          | `string`                                     |           | 外层 Dom 的类名                                                                                                                                                                          |
| body               | [SchemaNode](../../docs/types/schemanode)    |           | 内容容器                                                                                                                                                                                 |
| api                | [api](../../docs/types/api)                  |           | 配置项接口地址                                                                                                                                                                           |
| source             | [数据映射](../../docs/concepts/data-mapping) |           | 通过数据映射获取数据链中变量值作为配置                                                                                                                                                   |
| initFetch          | `boolean`                                    |           | 组件初始化时，是否请求接口                                                                                                                                                               |
| interval           | `number`                                     |           | 刷新时间(最小 1000)                                                                                                                                                                      |
| config             | `object` 或 `string`                         |           | 设置 eschars 的配置项,当为`string`的时候可以设置 function 等配置项                                                                                                                       |
| style              | `object`                                     |           | 设置根元素的 style                                                                                                                                                                       |
| width              | `string`                                     |           | 设置根元素的宽度                                                                                                                                                                         |
| height             | `string`                                     |           | 设置根元素的高度                                                                                                                                                                         |
| replaceChartOption | `boolean`                                    | `false`   | 每次更新是完全覆盖配置项还是追加？                                                                                                                                                       |
| trackExpression    | `string`                                     |           | 当这个表达式的值有变化时更新图表                                                                                                                                                         |
| dataFilter         | `string`                                     |           | 自定义 echart config 转换，函数签名：function(config, echarts, data) {return config;} 配置时直接写函数体。其中 config 是当前 echart 配置，echarts 就是 echarts 对象，data 为上下文数据。 |
| mapURL             | [api](../../docs/types/api)                  |           | 地图 geo json 地址                                                                                                                                                                       |
| mapName            | string                                       |           | 地图名称                                                                                                                                                                                 |
| loadBaiduMap       | boolean                                      |           | 加载百度地图                                                                                                                                                                             |

## 事件表

> 2.4.1 及以上版本

当前组件会对外派发以下事件，可以通过`onEvent`来监听这些事件，并通过`actions`来配置执行的动作，在`actions`中可以通过`${事件参数名}`或`${event.data.[事件参数名]}`来获取事件产生的数据，详细请查看[事件动作](../../docs/concepts/event-action)。

| 事件名称            | 事件参数                                                                             | 说明                                                |
| ------------------- | ------------------------------------------------------------------------------------ | --------------------------------------------------- |
| init                | -                                                                                    | 组件实例被创建并插入 DOM 中时触发。2.4.1 及以上版本 |
| click               | 查看[ECharst 事件与行为文档](https://echarts.apache.org/handbook/zh/concepts/event/) | 鼠标点击时触发                                      |
| mouseover           | 查看[ECharst 事件与行为文档](https://echarts.apache.org/handbook/zh/concepts/event/) | 鼠标悬浮时触发                                      |
| legendselectchanged | 查看[ECharst 事件与行为文档](https://echarts.apache.org/handbook/zh/concepts/event/) | 切换图例选中状态时触发                              |
| finished | {echarts: echarts.init(ref, theme)} | echarts 图表绘制完成, version > 6.11.0                              |

### init

```schema: scope="body"
{
    "type": "chart",
    "id": "chart01",
    "api": "/api/mock2/chart/chartData",
    "config": {
      "xAxis": {
        "type": "category",
        "data": [
          "Mon",
          "Tue",
          "Wed",
          "Thu",
          "Fri",
          "Sat"
        ]
      },
      "yAxis": {
        "type": "value"
      },
      "series": [
        {
          "data": "${line || []}",
          "type": "line"
        }
      ]
    },
    "onEvent": {
        "init": {
            "actions": [
            {
                "actionType": "toast",
                "args": {
                    "msg": "init"
                }
            }
            ]
        }
    }
}
```

### click

用户鼠标操作点击时触发，例如点击下图蓝色线条上的数据点，将弹出详情。

```
/* Detailed source-code truncated for AI context efficiency. */
```

### mouseover

用户鼠标悬浮时触发，例如悬浮到下图蓝色线条上的数据点，将弹出详情。

```
/* Detailed source-code truncated for AI context efficiency. */
```

### legendselectchanged

图例开关的行为会触发 legendselectchanged 事件。

```
/* Detailed source-code truncated for AI context efficiency. */
```


### finished

echarts渲染完触发`finished`事件, version>6.11.0。

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 动作表

当前组件对外暴露以下特性动作，其他组件可以通过指定`actionType: 动作名称`、`componentId: 该组件id`来触发这些动作，动作配置可以通过`args: {动作配置项名称: xxx}`来配置具体的参数，详细请查看[事件动作](../../docs/concepts/event-action#触发其他组件的动作)。

| 动作名称 | 动作配置                   | 说明                                       |
| -------- | -------------------------- | ------------------------------------------ |
| reload   | -                          | 刷新（重新加载）                           |
| setValue | `value: object` 更新的数据 | 更新数据，等于更新图表所依赖数据域中的变量 |

2.4.1 及以上版本，除了以上动作，还支持直接触发[ECharts 组件行为](https://echarts.apache.org/handbook/zh/concepts/event/#%E4%BB%A3%E7%A0%81%E8%A7%A6%E5%8F%91-echarts-%E4%B8%AD%E7%BB%84%E4%BB%B6%E7%9A%84%E8%A1%8C%E4%B8%BA)，即通过`actionType`指定行为名称，行为配置通过`args: {动作配置项名称: xxx}`来配置具体的参数。

### reload

#### 只做刷新

重新发送`api`请求，刷新 Chart 时，只配置`componentId`目标组件 ID 即可。

```schema: scope="body"
[
    {
      "type": "button",
      "label": "刷新请求",
      "onEvent": {
        "click": {
          "actions": [
            {
              "componentId": "chart01",
              "actionType": "reload"
            }
          ]
        }
      }
    },
    {
    "type": "chart",
    "id": "chart01",
    "api": "/api/mock2/chart/chartData",
    "config": {
      "xAxis": {
        "type": "category",
        "data": [
          "Mon",
          "Tue",
          "Wed",
          "Thu",
          "Fri",
          "Sat"
        ]
      },
      "yAxis": {
        "type": "value"
      },
      "series": [
        {
          "data": "${line || []}",
          "type": "line"
        }
      ]
    }
  }
]
```

#### 发送数据并刷新

刷新 Chart 组件时，如果配置了`data`，将发送`data`给目标组件，并将该数据合并到目标组件的数据域中（如果配置`"dataMergeMode": "override"`将覆盖目标组件的数据），然后重新请求数据。

```schema: scope="body"
[
    {
      "type": "button",
      "label": "刷新请求",
      "onEvent": {
        "click": {
          "actions": [
            {
              "componentId": "chart01",
              "actionType": "reload",
              "data": {
                "xAxis": [
                  "周一",
                  "周二",
                  "周三",
                  "周四",
                  "周五",
                  "周六"
                ]
              }
            }
          ]
        }
      }
    },
    {
    "type": "chart",
    "id": "chart01",
    "data": {
      "xAxis": [
        "Mon",
        "Tue",
        "Wed",
        "Thu",
        "Fri",
        "Sat"
      ]
    },
    "api": "/api/mock2/chart/chartData",
    "config": {
      "xAxis": {
        "type": "category",
        "data": "${xAxis}"
      },
      "yAxis": {
        "type": "value"
      },
      "series": [
        {
          "data": "${line || []}",
          "type": "line"
        }
      ]
    }
  }
]
```

### setValue

通过`setValue`更新指定图表的数据。

#### 合并数据

默认`setValue`会将新数据与目标组件数据进行合并。

```schema: scope="body"
[
    {
      "type": "button",
      "label": "更新数据",
      "onEvent": {
        "click": {
          "actions": [
            {
              "componentId": "chart02",
              "actionType": "setValue",
              "args": {
                "value": {
                  "line":[98,41,51,2,90,40]
                }
              }
            }
          ]
        }
      }
    },
    {
    "type": "chart",
    "id": "chart02",
    "data": {
      "xAxis": [
          "Mon",
          "Tue",
          "Wed",
          "Thu",
          "Fri",
          "Sat"
        ]
    },
    "api": "/api/mock2/chart/chartData",
    "config": {
      "xAxis": {
        "type": "category",
        "data": "${xAxis}"
      },
      "yAxis": {
        "type": "value"
      },
      "series": [
        {
          "data": "${line || []}",
          "type": "line"
        }
      ]
    }
  }
]
```

#### 覆盖数据

可以通过`"dataMergeMode": "override"`来覆盖目标组件数据。

```schema: scope="body"
[
    {
      "type": "button",
      "label": "更新数据",
      "onEvent": {
        "click": {
          "actions": [
            {
              "componentId": "chart02",
              "actionType": "setValue",
              "args": {
                "value": {
                  "line":[98,41,51,2,90,40]
                }
              },
              "dataMergeMode": "override"
            }
          ]
        }
      }
    },
    {
    "type": "chart",
    "id": "chart02",
    "data": {
      "xAxis": [
          "Mon",
          "Tue",
          "Wed",
          "Thu",
          "Fri",
          "Sat"
        ]
    },
    "api": "/api/mock2/chart/chartData",
    "config": {
      "xAxis": {
        "type": "category",
        "data": "${xAxis}"
      },
      "yAxis": {
        "type": "value"
      },
      "series": [
        {
          "data": "${line || []}",
          "type": "line"
        }
      ]
    }
  }
]
```

### 其他动作

```
/* Detailed source-code truncated for AI context efficiency. */
```

---

### Zh CN Components Code (`docs/zh-CN/components/code.md`)

---
title: Code 代码高亮
description:
type: 0
group: ⚙ 组件
menuName: Code
icon:
order: 38
---

使用代码高亮的方式来显示一段代码。

## 基本用法

```schema: scope="body"
{
  "type": "code",
  "language": "html",
  "value": "<div>html</div>"
}
```

## 语言设置

默认语言是 html，可以通过 language 指定以下语言：

`bat`、 `c`、 `coffeescript`、 `cpp`、 `csharp`、 `css`、 `dockerfile`、 `fsharp`、 `go`、 `handlebars`、 `html`、 `ini`、 `java`、 `javascript`、 `json`、 `less`、 `lua`、 `markdown`、 `msdax`、 `objective-c`、 `php`、 `plaintext`、 `postiats`、 `powershell`、 `pug`、 `python`、 `r`、 `razor`、 `ruby`、 `sb`、 `scss`、`shell`、 `sol`、 `sql`、 `swift`、 `typescript`、 `vb`、 `xml`、 `yaml`

```schema
{
  "body": {
    "type": "code",
    "language": "javascript",
    "value": "(function () {\n  let amis = amisRequire('amis/embed');\n  let amisJSON = {\n    type: 'page',\n    title: '表单页面',\n    body: {\n      type: 'form',\n      mode: 'horizontal',\n      api: '/saveForm',\n      body: [\n        {\n          label: 'Name',\n          type: 'input-text',\n          name: 'name'\n        },\n        {\n          label: 'Email',\n          type: 'input-email',\n          name: 'email'\n        }\n      ]\n    }\n  };\n  let amisScoped = amis.embed('#root', amisJSON);\n})();"
  }
}
```

language 支持从上下文获取数据

```schema
{
  "type": "page",
  "data": {
    "lang": "javascript"
  },
  "body": {
    "type": "code",
    "language": "${lang}",
    "value": "function amis() {\n  console.log('amis');\n}"
  }
}
```

## 动态数据

可以使用 name 来从上下文来获取数据，比如

```schema
{
  "type": "page",
  "data": {
    "sourcecode": "<div>html</div>"
  },
  "body": {
    "type": "code",
    "language": "html",
    "name": "sourcecode"
  }
}
```

因此它还能放在表单、crud 中实现代码的展现。

## 主题及 tab 大小

通过 `editorTheme` 设置主题，`tagSize` 设置 tab 宽度

```schema: scope="body"
{
  "type": "code",
  "language": "javascript",
  "tagSize": 4,
  "value": "function amis() {\n\tconsole.log('amis');\n}"
}

```

## 超出换行

> 1.5.1 及以上版本

通过 `wordWrap` 设置是否折行，默认是折行

```schema: scope="body"
{
  "type": "code",
  "language": "typescript",
  "tagSize": 4,
  "wordWrap": false,
  "value": "function amis() {\n\tconsole.log('amis')\tconsole.log('amis')\tconsole.log('amis')\tconsole.log('amis')\tconsole.log('amis')\tconsole.log('amis');\n}"
}
```

## 最大高度

通过配置 `maxHeight` 可以实现最大高度，超出滚动

```schema
{
  "body": {
    "type": "code",
    "language": "javascript",
    "className": "b-a",
    "maxHeight": 200,
    "value": "(function () {\n  let amis = amisRequire('amis/embed');\n  let amisJSON = {\n    type: 'page',\n    title: '表单页面',\n    body: {\n      type: 'form',\n      mode: 'horizontal',\n      api: '/saveForm',\n      body: [\n        {\n          label: 'Name',\n          type: 'input-text',\n          name: 'name'\n        },\n        {\n          label: 'Email',\n          type: 'input-email',\n          name: 'email'\n        }\n      ]\n    }\n  };\n  let amisScoped = amis.embed('#root', amisJSON);\n})();"
  }
}
```

## 自定义语言高亮

还可以通过 `customLang` 参数来自定义高亮，详情参考[示例](../../../examples/code)。

`customLang` 中主要是 `tokens` 设置，这里是语言词法配置，它有 4 个配置项：

- `name`：词法名称
- `regex`：词法的正则匹配，注意因为是在字符串中，这里正则中如果遇到 `\` 需要写成 `\\`
- `regexFlags`: 可选，正则的标志参数
- `color`：颜色
- `fontStyle`: 可选，字体样式，比如 `bold` 代表加粗

## 属性表

| 属性名      | 类型               | 默认值 | 说明                               |
| ----------- | ------------------ | ------ | ---------------------------------- |
| className   | `string`           |        | 外层 CSS 类名                      |
| value       | `string`           |        | 显示的颜色值                       |
| name        | `string`           |        | 在其他组件中，时，用作变量映射     |
| language    | `string`           |        | 所使用的高亮语言，默认是 plaintext |
| tabSize     | `number`           | 4      | 默认 tab 大小                      |
| editorTheme | `string`           | 'vs'   | 主题，还有 'vs-dark'               |
| wordWrap    | `string`           | `true` | 是否折行                           |
| maxHeight   | `string`\|`number` |        | 最大高度                           |

---

### Zh CN Components Collapse (`docs/zh-CN/components/collapse.md`)

---
title: Collapse 折叠器
description:
type: 0
group: ⚙ 组件
menuName: Collapse 折叠器
icon:
order: 36
---

## 基本用法

```schema: scope="body"
{
    "type": "collapse-group",
    "activeKey": ["1"],
    "body": [
      {
        "type": "collapse",
        "key": "1",
        "header": "标题1",
        "body": "这里是内容1"
      },
      {
        "type": "collapse",
        "key": "2",
        "header": "标题2",
        "body": "这里是内容2"
      },
      {
        "type": "collapse",
        "key": "3",
        "header": "标题3",
        "body": "这里是内容3"
      }
    ]
}
```

## 手风琴模式

```schema: scope="body"
{
    "type": "collapse-group",
    "activeKey": ["1"],
    "accordion": true,
    "body": [
      {
        "type": "collapse",
        "key": "1",
        "header": "标题1",
        "body": "这里是内容1"
      },
      {
        "type": "collapse",
        "key": "2",
        "header": "标题2",
        "body": "这里是内容2"
      },
      {
        "type": "collapse",
        "key": "3",
        "header": "标题3",
        "body": "这里是内容3"
      }
    ]
}
```

## 自定义图标

```schema: scope="body"
{
    "type": "collapse-group",
    "activeKey": ["1"],
    "expandIcon": {
      "type": "icon",
      "icon": "caret-right"
    },
    "body": [
      {
        "type": "collapse",
        "key": "1",
        "header": "标题1",
        "body": "这里是内容1"
      },
      {
        "type": "collapse",
        "key": "2",
        "header": "标题2",
        "body": "这里是内容2"
      },
      {
        "type": "collapse",
        "key": "3",
        "header": "标题3",
        "body": "这里是内容3"
      }
    ]
}
```

## 设置图标位置

```schema: scope="body"
{
    "type": "collapse-group",
    "expandIconPosition": "right",
    "activeKey": ["1"],
    "body": [
      {
        "type": "collapse",
        "key": "1",
        "header": "标题1",
        "body": "这里是内容1"
      },
      {
        "type": "collapse",
        "key": "2",
        "header": "标题2",
        "body": "这里是内容2"
      },
      {
        "type": "collapse",
        "key": "3",
        "header": "标题3",
        "body": "这里是内容3"
      }
    ]
}
```

## 面板嵌套

```schema: scope="body"
{
    "type": "collapse-group",
    "activeKey": ["1"],
    "body": [
      {
        "type": "collapse",
        "key": "1",
        "header": "标题1",
        "body": {
          "type": "collapse-group",
          "activeKey": ["1"],
          "body": [
            {
              "type": "collapse",
              "key": "1",
              "header": "嵌套面板标题",
              "body": "嵌套面板内容"
            }
          ]
        }
      },
      {
        "type": "collapse",
        "key": "2",
        "header": "标题2",
        "body": "这里是内容2"
      }
    ]
}
```

## 折叠面板禁用

```schema: scope="body"
{
    "type": "collapse-group",
    "activeKey": ["1"],
    "body": [
      {
        "type": "collapse",
        "key": "1",
        "header": "标题1",
        "body": "这里是内容1"
      },
      {
        "type": "collapse",
        "disabled": true,
        "key": "2",
        "header": "标题2",
        "body": "这里是内容2"
      }
    ]
}
```

## 折叠面板图标隐藏

```schema: scope="body"
{
    "type": "collapse-group",
    "body": [
      {
        "type": "collapse",
        "key": "1",
        "header": "标题1",
        "body": "这里是内容1"
      },
      {
        "type": "collapse",
        "showArrow": false,
        "key": "2",
        "header": "标题2",
        "body": "这里是内容2"
      }
    ]
}
```

## 类FieldSet样式

当Collapse组件作为Form组件的子元素时，`enableFieldSetStyle`属性可以控制Collapse组件样式风格，开启后转换为类似[FieldSet组件](./form/fieldset)的样式，默认开启。


```schema: scope="body"
{
  "type": "form",
  "body": [
    {
      "type": "switch",
      "name": "enableFieldSetStyle",
      "label": "切换展示方式",
      "mode": "horizontal",
      "value": true
    },
    {
      "type": "collapse-group",
      "activeKey": ["1"],
      "enableFieldSetStyle": "${enableFieldSetStyle}",
      "body": [
        {
          "type": "collapse",
          "key": "1",
          "header": "标题1",
          "body": "这里是内容1"
        },
        {
          "type": "collapse",
          "key": "2",
          "header": "标题2",
          "body": "这里是内容2"
        },
        {
          "type": "collapse",
          "key": "3",
          "header": "标题3",
          "body": "这里是内容3"
        }
      ]
    }
  ]
}
```

## CollapseGroup 属性表

| 属性名             | 类型                                                   | 默认值             | 说明                                | 版本 |
| ------------------ | ------------------------------------------------------ | ------------------ | ----------------------------------- | --- |
| type               | `string`                                               | `"collapse-group"` | 指定为 collapse-group 渲染器        |
| activeKey          | `Array<string \| number \| never> \| string \| number` | -                  | 初始化激活面板的 key                |
| accordion          | `boolean`                                              | `false`            | 手风琴模式                          |
| expandIcon         | `SchemaNode`                                           | -                  | 自定义切换图标                      |
| expandIconPosition | `string`                                               | `"left"`           | 设置图标位置，可选值`left \| right` |
| enableFieldSetStyle | `boolean`              | `true`       | 当Collapse作为Form组件的子元素时，开启该属性后组件样式设置为FieldSet组件的样式，默认开启           | `3.5.0` |


## CollapseGroup 事件表

当前组件会对外派发以下事件，可以通过 onEvent 来监听这些事件，并通过 actions 来配置执行的动作，在 actions 中可以通过${事件参数名}或${event.data.[事件参数名]}来获取事件产生的数据，详细查看事件动作。

| 事件名称 | 事件参数                                                                                                                                        | 说明                       |
| -------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- |
| change   | `activeKeys: Array<string \| number>` 当前展开的索引列表 <br /> `collapseId: string \| number` 折叠器索引 <br/> `collapsed: boolean` 折叠器状态 | 折叠面板折叠状态改变时触发 |

### change

折叠面板折叠状态改变时触发。

```schema: scope="body"
{
  "type": "collapse-group",
  "activeKey": [
    "1"
  ],
  "body": [
    {
      "type": "collapse",
      "key": "1",
      "active": true,
      "header": "标题1",
      "body": [
        {
          "type": "tpl",
          "tpl": "这里是内容1",
          "wrapperComponent": "",
          "inline": false,
          "id": "u:757ad799da08"
        }
      ],
      "id": "u:b1b68dfbb08d"
    },
    {
      "type": "collapse",
      "key": "2",
      "header": "标题2",
      "body": [
        {
          "type": "tpl",
          "tpl": "这里是内容1",
          "wrapperComponent": "",
          "inline": false,
          "id": "u:92caa03f227e"
        }
      ],
      "id": "u:621a22c8b18c"
    }
  ],
  "id": "u:23e4c5ec9c89",
  "onEvent": {
    "change": {
      "weight": 0,
      "actions": [
        {
          "actionType": "toast",
          "args": {
            "msgType": "info",
            "position": "top-right",
            "closeButton": true,
            "showIcon": true,
            "title": "折叠状态改变",
            "msg": "activeKeys: ${event.data.activeKeys | json}, collapseId: ${event.data.collapseId}, collapsed: ${event.data.collapsed}",
            "className": "theme-toast-action-scope"
          }
        }
      ]
    }
  }
}
```

## Collapse 属性表

| 属性名    | 类型                   | 默认值       | 说明                   | 版本 |
| --------- | ---------------------- | ------------ | ---------------------- | --- |
| type      | `string`               | `"collapse"` | 指定为 collapse 渲染器 |
| disabled  | `boolean`              | `false`      | 禁用                   |
| collapsed | `boolean`              | `true`       | 初始状态是否折叠       |
| key       | `string \| number`     | -            | 标识                   |
| header    | `string \| SchemaNode` | -            | 标题                   |
| body      | `string \| SchemaNode` | -            | 内容                   |
| showArrow | `boolean`              | `true`       | 是否展示图标           |

## Collapse 事件表

当前组件会对外派发以下事件，可以通过 onEvent 来监听这些事件，并通过 actions 来配置执行的动作，在 actions 中可以通过${事件参数名}或${event.data.[事件参数名]}来获取事件产生的数据，详细查看事件动作。

| 事件名称 | 事件参数                        | 说明                     |
| -------- | ------------------------------- | ------------------------ |
| change   | `collapsed: boolean` 折叠器状态 | 折叠器折叠状态改变时触发 |

### change

折叠面板折叠状态改变时触发。

```schema: scope="body"
{
  "type": "collapse",
  "header": "标题",
  "body": [
    {
      "type": "tpl",
      "tpl": "内容",
      "wrapperComponent": "",
      "inline": false,
      "id": "u:6588c12ee3b0"
    }
  ],
  "id": "u:62aa2f0c7fd9",
  "onEvent": {
    "change": {
      "weight": 0,
      "actions": [
        {
          "actionType": "toast",
          "args": {
            "msgType": "info",
            "position": "top-right",
            "closeButton": true,
            "showIcon": true,
            "title": "collapsedChange",
            "msg": "collapsed: ${event.data.collapsed}",
            "className": "theme-toast-action-scope"
          }
        }
      ]
    }
  }
}
```

---

### Zh CN Components Color (`docs/zh-CN/components/color.md`)

---
title: Color 颜色
description:
type: 0
group: ⚙ 组件
menuName: Color
icon:
order: 37
---

用于展示颜色

## 基本用法

```schema
{
    "type": "page",
    "body": {
        "type": "color",
        "value": "#108cee"
    }
}
```

## 用作 Field 时

当用在 Table 的列配置 Column、List 的内容、Card 卡片的内容和表单的 Static-XXX 中时，可以设置`name`属性，映射同名变量

### Table 中的列类型

```schema: scope="body"
{
    "type": "table",
    "data": {
        "items": [
            {
                "id": "1",
                "color": "#108cee"
            },
            {
                "id": "2",
                "color": "#f38900"
            },
            {
                "id": "3",
                "color": "#04c1ba"
            }
        ]
    },
    "columns": [
        {
            "name": "id",
            "label": "Id"
        },

        {
            "name": "color",
            "label": "颜色",
            "type": "color"
        }
    ]
}
```

List 的内容、Card 卡片的内容配置同上

### Form 中静态展示

```schema: scope="body"
{
    "type": "form",
    "data": {
        "color": "#108cee"
    },
    "body": [
        {
            "type": "static-color",
            "name": "color",
            "label": "颜色"
        }
    ]
}
```

## 属性表

| 属性名                   | 类型      | 默认值 | 说明                                                                                   | |
| ------------------------ | --------- | ------ | -------------------------------------------------------------------------------------- | ------- |
| type                     | `string`  |        | 如果在 Table、Card 和 List 中，为`"color"`；在 Form 中用作静态展示，为`"static-color"` |
| className                | `string`  |        | 外层 CSS 类名                                                                          |
| value                    | `string`  |        | 显示的颜色值                                                                           |
| name                     | `string`  |        | 在其他组件中，时，用作变量映射                                                         |
| defaultColor             | `string`  |        | 默认颜色值                                                                             |
| showValue                | `boolean` | `true` | 是否显示右边的颜色值                                                                   |
| popOverContainerSelector | `string`  |        | 弹层挂载位置选择器，会通过`querySelector`获取                                          | `6.4.2` |

---

### Zh CN Components Container (`docs/zh-CN/components/container.md`)

---
title: Container 容器
description:
type: 0
group: ⚙ 组件
menuName: Container 容器
icon:
order: 38
---

Container 是一种容器组件，它可以渲染其他 amis 组件。

注意 Container 组件因为历史原因多了一层 div，推荐使用 [wrapper](wrapper) 来作为容器。

## 基本用法

```schema: scope="body"
{
    "type": "container",
    "body": "这里是容器内容区"
}
```

### style

container 可以通过 style 来设置样式，比如背景色或背景图，注意这里的属性是使用驼峰写法，是 `backgroundColor` 而不是 `background-color`。

```schema: scope="body"
{
    "type": "container",
    "style": {
        "backgroundColor": "#C4C4C4"
    },
    "body": "这里是容器内容区"
}
```

### wrapperComponent

修改标签名可以让容器使用其它标签渲染，比如 `pre`

```schema: scope="body"
{
    "type": "container",
    "wrapperComponent": "pre",
    "body": "var a = 1;"
}
```

## 属性表

| 属性名           | 类型                                      | 默认值        | 说明                    |
| ---------------- | ----------------------------------------- | ------------- | ----------------------- |
| type             | `string`                                  | `"container"` | 指定为 container 渲染器 |
| className        | `string`                                  |               | 外层 Dom 的类名         |
| bodyClassName    | `string`                                  |               | 容器内容区的类名        |
| wrapperComponent | `string`                                  | `"div"`       | 容器标签名              |
| style            | `Object`                                  |               | 自定义样式              |
| body             | [SchemaNode](../../docs/types/schemanode) |               | 容器内容                |

## 事件表

> 3.3.0 及以上版本

当前组件会对外派发以下事件，可以通过`onEvent`来监听这些事件，并通过`actions`来配置执行的动作，在`actions`中可以通过`${事件参数名}`或`${event.data.[事件参数名]}`来获取事件产生的数据，详细查看[事件动作](../../docs/concepts/event-action)。

| 事件名称   | 事件参数 | 说明           |
| ---------- | -------- | -------------- |
| click      | -        | 点击时触发     |
| mouseenter | -        | 鼠标移入时触发 |
| mouseleave | -        | 鼠标移出时触发 |

### click

鼠标点击。可以尝试通过`${event.context.nativeEvent}`获取鼠标事件对象。

```schema: scope="body"
{
    "type": "container",
    "body": "这里是容器内容区",
    "onEvent": {
        "click": {
            "actions": [
                {
                    "actionType": "toast",
                    "args": {
                        "msgType": "info",
                        "msg": "${event.context.nativeEvent.type}"
                    }
                }
            ]
        }
    }
}
```

### mouseenter

鼠标移入。可以尝试通过`${event.context.nativeEvent}`获取鼠标事件对象。

```schema: scope="body"
{
    "type": "container",
    "body": "这里是容器内容区",
    "onEvent": {
        "mouseenter": {
            "actions": [
                {
                    "actionType": "toast",
                    "args": {
                        "msgType": "info",
                        "msg": "${event.context.nativeEvent.type}"
                    }
                }
            ]
        }
    }
}
```

### mouseleave

鼠标移出。可以尝试通过`${event.context.nativeEvent}`获取鼠标事件对象。

```schema: scope="body"
{
    "type": "container",
    "body": "这里是容器内容区",
    "onEvent": {
        "mouseleave": {
            "actions": [
                {
                    "actionType": "toast",
                    "args": {
                        "msgType": "info",
                        "msg": "${event.context.nativeEvent.type}"
                    }
                }
            ]
        }
    }
}
```

---

### Zh CN Components Crud (`docs/zh-CN/components/crud.md`)

---
title: CRUD 增删改查
description:
type: 0
group: ⚙ 组件
menuName: CRUD 增删改查
icon:
order: 25
---

CRUD，即增删改查组件，主要用来展现数据列表，并支持各类【增】【删】【改】【查】等操作。

注意 CRUD 所需的数据必须放 items 中，因此如果只是想显示表格类型的数据没有分页，请使用 [Table](./table)。

## 基本用法

最基本的用法是配置 **数据源接口(api)** 以及 **展示列(columns)**

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 数据源接口

### 数据结构

CRUD 组件对数据源接口的数据结构要求如下：

- `items`或`rows`：用于返回数据源数据，格式是数组
- `total`或`count`: 用于返回数据库中一共有多少条数据，用于生成分页

```json
{
  "status": 0,
  "msg": "",
  "data": {
    "items": [
      {
        // 每一行的数据
        "id": 1,
        "xxx": "xxxx"
      }
    ],

    "total": 200 // 注意！！！这里不是当前请求返回的 items 的长度，而是数据库中一共有多少条数据，用于生成分页组件
    // 如果你不想要分页，把这个不返回就可以了。
  }
}
```

如果想要通过接口控制当前所处在第几页，可以返回字段 `page`（或自定义字段 `pageField` 的值）。

```json
{
  "status": 0,
  "msg": "",
  "data": {
    "items": [
      {
        // 每一行的数据
        "id": 1,
        "xxx": "xxxx"
      }
    ],

    "total": 200,
    "page": 20
  }
}
```

如果无法知道数据总数，只能知道是否有下一页，请返回如下格式，amis 会简单生成一个简单版本的分页控件。

```json
{
  "status": 0,
  "msg": "",
  "data": {
    "items": [
      {
        // 每个成员的数据。
        "id": 1,
        "xxx": "xxxx"
      }
    ],

    "hasNext": true // 是否有下一页。
  }
}
```

如果不需要分页，或者配置了 `loadDataOnce` 则可以忽略掉 `total` 和 `hasNext` 参数。

### Query 参数

数据源接口地址可以通过变量实现动态拼接，例如： `/api/mock2/sample/${id}`，但需要注意的是接口地址拼接变量后，amis 就不会自动追加默认参数了，例如：分页参数、查询参数等，如需追加，可以自行拼接，例如： `/api/mock2/sample/${id}?page=${page}&perPage=${perPage}`

默认的分页参数是 `page` 和 `perPage`，page 代表页数，比如第一页，perPage 代表每页显示几行。

如果要其它格式，比如转成 `limit` 和 `offset`，可以使用公式来转换，比如

`/api/mock2/sample?limit=${perPage}&offset=${(page - 1) * perPage}`

### 参数汇总

这里汇总一下 CRUD 里默认用到的 query 列表

| query 名 | 类型         | 说明                           |
| -------- | ------------ | ------------------------------ |
| page     | number       | 分页，从 1 开始                |
| perPage  | number       | 每页数量                       |
| orderBy  | string       | 排序字段，目前 CRUD 只支持一个 |
| orderDir | 'asc'/'desc' | 排序方式                       |
| keywords | string       | 搜索关键字                     |

### 解析 Query 原始类型

> `3.5.0`及以上版本

`syncLocation`开启后，CRUD 在初始化数据域时，将会对 url 中的 Query 进行转换，将原始类型的字符串格式的转化为同位类型。`3.6.0`版本后支持对象格式，该配置默认开启，且默认仅转化布尔值。

#### ParsePrimitiveQueryOptions

```typescript
interface ParsePrimitiveQueryOptions {
  parsePrimitiveQuery: {
    enable: boolean;
    types?: ('boolean' | 'number')[];
  };
}
```

比如开启设置 `{"parsePrimitiveQuery": {"enable": true, "types": ["boolean", "number"]}}` 后：

```
"true"   ==> true
"false"  ==> false
"123"    ==> 123
"123.4"  ==> 123.4
```

如果只想保持字符串格式，可以设置`"parsePrimitiveQuery": false` 或者 `"parsePrimitiveQuery": {"enable": false}` 关闭该特性，具体效果参考[示例](../../../examples/crud/parse-primitive-query)。如果想实现字段定制化转化类型，可以使用[配置 API 请求数据](../../docs/types/api#配置请求数据)，通过表达式控制接口传递的参数类型。

## 功能

既然这个渲染器叫增删改查，那接下来分开介绍这几个功能吧。

### 增

其实这个渲染器并没有包含新增功能，新增功能其实还是依靠其他位置放个弹框表单完成，弹框完事了会自动让页面里面的 CRUD 刷新如：

```
/* Detailed source-code truncated for AI context efficiency. */
```

当然如果你不想要自动刷新，那么给按钮配置 reload: "none" 就行了。

### 删

删除功能主要有三种实现：[单条操作](#单条操作)、[批量操作](#批量操作)或者直接添加一个操作栏，在里面放个类型为 ajax 类型的按钮即可。在这个按钮里面能获得对应的行数据，而且完成后也会自动刷新这个 CRUD 列表。

```schema: scope="body"
{
    "type": "crud",
    "api": "/api/mock2/sample?orderBy=id&orderDir=desc",
    "syncLocation": false,
    "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "engine",
            "label": "Rendering engine"
        },
        {
            "name": "browser",
            "label": "Browser"
        },
        {
            "type": "operation",
            "label": "操作",
            "buttons": [
                {
                    "label": "删除",
                    "type": "button",
                    "actionType": "ajax",
                    "level": "danger",
                    "confirmText": "确认要删除？",
                    "api": "delete:/api/mock2/sample/${id}"
                }
            ]
        }
    ]
}
```

### 改

改和删其实是差不多的，唯一的区别在于，配置不同的 api，按钮类型改成弹框。

```
/* Detailed source-code truncated for AI context efficiency. */
```

弹框里面可用数据自动就是点击的那一行的行数据，如果列表没有返回，可以在 form 里面再配置个 initApi 初始化数据，如果行数据里面有倒是不需要再拉取了。表单项的 name 跟数据 key 对应上便自动回显了。默认发送给表单的保存接口只会包含配置了的表单项，如果不够，请在 api 上配置数据映射，或者直接添加 hidden 类型的表单项（即隐藏域 input[type=hidden]）。

### 查

除了列表查询外，还支持查看详情场景，与编辑不同的地方主要在于弹窗中改成放展示类组件，或者表单项配置静态展示。

```
/* Detailed source-code truncated for AI context efficiency. */
```

弹框里面可用数据自动就是点击的那一行的行数据，如果列表没有返回，可以在 form 里面再配置个 initApi 初始化数据，如果行数据里面有倒是不需要再拉取了。表单项的 name 跟数据 key 对应上便自动回显了。

## 展示模式

CRUD 支持下面 3 种展示模式，默认为 Table 表格模式。

### Table 表格模式

Table 模式支持 [Table](./table) 中的所有功能。

```schema: scope="body"
{
    "type": "crud",
    "api": "/api/mock2/sample",
    "syncLocation": false,
    "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "engine",
            "label": "Rendering engine"
        },
        {
            "name": "browser",
            "label": "Browser"
        },
        {
            "name": "platform",
            "label": "Platform(s)"
        },
        {
            "name": "version",
            "label": "Engine version"
        }
    ]
}
```

这个模式下会默认开启固定表头功能，如果不需要可以使用 `"affixHeader": false` 关闭。

### List 列表模式

List 模式支持 [List](./list) 中的所有功能。

```schema: scope="body"
{
"type": "crud",
"api": "/api/mock2/crud/permissions",
"mode": "list",
"placeholder": "当前组内, 还没有配置任何权限.",
"syncLocation": false,
"title": null,
"listItem": {
  "title": "$name",
  "subTitle": "$description",
  "actions": [
    {
      "icon": "fa fa-edit",
      "className": "mr-4",
      "tooltip": "编辑",
      "actionType": "dialog",
      "dialog": {
        "title": "编辑能力（权限）",
        "body": {
          "type": "form",
          "body": [
          {
            "type": "hidden",
            "name": "id"
          },
          {
            "name": "name",
            "label": "权限名称",
            "type": "input-text",
            "disabled": true
          },
          {
            "type": "divider"
          },
          {
            "name": "description",
            "label": "描述",
            "type": "textarea"
          }
        ]
        }
      }
    },
    {
      "tooltip": "删除",
      "disabledOn": "~[\"admin:permission\", \"admin:user\", \"admin:role\", \"admin:acl\", \"admin:page\", \"page:readAll\", \"admin:settings\"].indexOf(name)",
      "icon": "fa fa-times",
      "confirmText": "您确定要移除该权限?",
      "actionType": "ajax",
      "api": "delete:/api/mock2/notFound"
    }
  ]
}
}
```

### Cards 卡片模式

Cards 模式支持 [Cards](./cards) 中的所有功能。

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 嵌套

当行数据中存在 `children` 字段时，CRUD 会自动识别为树形数据，并支持展开收起。

```schema: scope="body"
{
    "type": "crud",
    "name": "crud",
    "syncLocation": false,
    "api": "/api/mock2/crud/table2",
    "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "engine",
            "label": "Rendering engine"
        },
        {
            "name": "browser",
            "label": "Browser"
        }
    ]
}
```

## 嵌套懒加载

如果数据量比较大不适合一次性加载，可以配置 `deferApi` 接口，结合行数据中标记 `defer: true` 属性，实现懒加载。

注意 `deferApi` 结果返回跟 `api` 返回不一样，`deferApi` 返回的是节点详情，而不是列表，列表应该是节点信息的 children 属性里面。也就是说 deferApi 还可以进一步完善节点信息。返回格式参考如下：

```
{
 status: 0,
 data: {
   id: 1,
   xxxProp: 'abc',
   children: [
     {
       id: 11,
       name: '子节点'
     }
   ]
 }
}
```

```schema: scope="body"
{
    "type": "crud",
    "name": "crud",
    "syncLocation": false,
    "api": "/api/mock2/crud/table6",
    "deferApi": "/api/mock2/crud/table6?parentId=${id}",
    "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "engine",
            "label": "Rendering engine"
        },
        {
            "name": "browser",
            "label": "Browser"
        }
    ]
}
```

## 查询条件表单

大部分表格展示有对数据进行检索的需求，CRUD 自身支持通过配置`filter`，实现查询条件过滤表单。`filter` 配置实际上同 [Form](./form/index) 组件，因此支持绝大部分`form`的功能。

在条件搜索区的 `Engine` 输入框中输入任意值查询会发现结果中 `ID` 为 1 - 3 的 `Rendering engine` 列因为返回值中没有对应字段值，被错误填入了与 `filter` 中相同 `name` 的字段值，这是因为表格 Cell 通过[数据链](../../docs/concepts/datascope-and-datachain)获取到了上层数据域 `filter` 中相同字段的数据值。这种情况可以在 CRUD `columns` 对应列配置`"canAccessSuperData": false`禁止访问父级数据域（比如: `Platform`列），或者 CRUD 追加`"canAccessSuperData": false`配置禁止所有列访问父级数据域。

```
/* Detailed source-code truncated for AI context efficiency. */
```

**请注意**：在默认没有自定义配置 api 数据映射时，提交查询条件表单，会自动将表单中的表单项值，发送给`crud`所配置的接口，然后通过后端接口，实现对数据的过滤操作，前端默认是不会进行任何的数据过滤操作

如果想前端实现过滤功能，请看[前端一次性加载](#前端一次性加载)部分。

### 自动生成查询区域

通过设置`"autoGenerateFilter": true`开启查询区域，会根据列元素的 `searchable` 属性值，自动生成查询条件表单，只有 `searchable` 属性值为合法的组件 Schema 时才会生成查询条件。注意这个属性和 `filter` 冲突，开启 `filter` 后 `autoGenerateFilter` 将会失效。

### autoGenerateFilter 属性表

| 属性名           | 类型      | 默认值 | 说明                 |
| ---------------- | --------- | ------ | -------------------- |
| columnsNum       | `number`  | `3`    | 过滤条件单行列数     |
| showBtnToolbar   | `boolean` | `true` | 是否显示设置查询字段 |
| defaultCollapsed | `boolean` | `true` | 是否初始收起         |

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 多个列表共用一套查询条件

如果希望一个查询表单作用在多个列表中，可以直接 `form + n * crud` 的方式。将 form 的提交目标给到多个 crud。

> 注意：如果一个页面有多个 crud，请控制同步地址栏的 crud 数量不要超过一个。否则会相互干扰

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 配置默认请求参数

可以配置`defaultParams`，来指定拉取接口时的默认参数：

```schema: scope="body"
{
    "type": "crud",
    "syncLocation": false,
    "api": "/api/mock2/sample",
    "defaultParams": {
        "perPage": 50
    },
    "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "engine",
            "label": "Rendering engine"
        },
        {
            "name": "browser",
            "label": "Browser"
        },
        {
            "name": "platform",
            "label": "Platform(s)"
        },
        {
            "name": "version",
            "label": "Engine version"
        },
        {
            "name": "grade",
            "label": "CSS grade"
        }
    ]
}
```

例如上例中，配置`{ perPage: 50 }`，指定分页的默认每页数据条数为 50 条。

## 数据源接口轮询

可以配置`interval`来实现数据接口轮询功能，最低为`1000`毫秒：

```schema: scope="body"
{
    "type": "crud",
    "syncLocation": false,
    "api": "/api/mock2/sample",
    "interval": 3000,
    "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "engine",
            "label": "Rendering engine"
        },
        {
            "name": "browser",
            "label": "Browser"
        },
        {
            "name": "platform",
            "label": "Platform(s)"
        },
        {
            "name": "version",
            "label": "Engine version"
        },
        {
            "name": "grade",
            "label": "CSS grade"
        }
    ]
}
```

配置`stopAutoRefreshWhen`表达式，来实现满足条件，停止轮询

## 列配置

除了支持 [Table 中的列配置](./table#%E5%88%97%E9%85%8D%E7%BD%AE) 以外，crud 还支持下面这些配置，帮助更好的操作数据

### 排序检索

可以在列上配置`"sortable": true`，该列表头右侧会渲染一个可点击的排序图标，可以切换`正序`和`倒序`。

> 如果想默认就基于某个字段排序，可以结合 `defaultParams` 一起配置。

```schema: scope="body"
{
    "type": "crud",
    "syncLocation": false,
    "api": "/api/mock2/sample",
    "defaultParams": {
      "orderBy": "engine",
      "orderDir": "desc"
    },
    "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "engine",
            "label": "Rendering engine",
            "sortable": true
        }
    ]
}
```

amis 只负责生成排序组件，并将排序参数传递给接口，而不会在前端对数据进行排序处理。参数格式如下：

```json
{
  "orderBy": "engine", // 这里为所配置列的 name
  "orderDir": "asc" // asc 为升序，desc 为降序
}
```

你可以通过[数据映射](../../docs/concepts/data-mapping)，在`api`中获取这些参数。

### 快速搜索

可以在列上配置`"searchable": true`，该列表头右侧会渲染一个可点击的搜索图标，点击可以输入关键字进行该列的搜索：

```schema: scope="body"
{
    "type": "crud",
    "syncLocation": false,
    "api": "/api/mock2/sample",
    "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "engine",
            "label": "Rendering engine",
            "searchable": true
        }
    ]
}
```

也可以通过`searchable`来自定义搜索表单

```schema: scope="body"
{
    "type": "crud",
    "syncLocation": false,
    "api": "/api/mock2/sample",
    "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "engine",
            "label": "Rendering engine",
            "searchable": {
              "type": "form",
              "wrapWithPanel": false,
              "body": [
                {
                  "type": "input-text",
                  "name": "engine"
                }
              ]
            }
        }
    ]
}
```

amis 只负责生成搜索组件，并将搜索参数传递给接口，而不会在前端对数据进行搜索处理。参数格式如下：

```json
{
  "engine": "xxx" // 这里的key是列的 name，value是输入的关键字
}
```

你可以通过[数据映射](../../docs/concepts/data-mapping)，在`api`中获取这些参数。

### 快速过滤

可以在列上配置`filterable`属性，该列表头右侧会渲染一个可点击的过滤图标，点击显示下拉框，选中进行过滤：

```schema: scope="body"
{
    "type": "crud",
    "syncLocation": false,
    "api": "/api/mock2/sample",
    "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "grade",
            "label": "CSS grade",
            "filterable": {
                "options": [
                    "A",
                    "B",
                    "C",
                    "D",
                    "X"
                ]
            }
        },
        {
            "name": "version",
            "label": "Version",
            "filterable": {
                "options": [
                    {"label": "0", "value": 0},
                    {"label": "1", "value": 1}
                ]
            }
        }
    ]
}
```

amis 只负责生成下拉选择器组件，并将搜索参数传递给接口，而不会在前端对数据进行搜索处理。参数格式如下：

```json
{
  "grade": "xxx" // 这里的key是列的 name，value是选中项的value值
}
```

你可以通过[数据映射](../../docs/concepts/data-mapping)，在`api`中获取这些参数。

#### 快速过滤支持检索

> 3.7.0 及以上版本

通过配置 `searchable` 支持选项检索

```schema: scope="body"
{
    "type": "crud",
    "syncLocation": false,
    "api": "/api/mock2/sample",
    "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "grade",
            "label": "CSS grade",
            "filterable": {
                "searchable": true,
                "options": [
                    "A",
                    "B",
                    "C",
                    "D",
                    "X"
                ]
            }
        }
    ]
}
```

如果需要更细节的配置，可以使用 `searchConfig`，详细配置项参考 search-box 组件

#### 下拉数据源

过滤器的数据域支持 API 接口和上下文数据(`3.6.0`及以上版本)

```schema
{
  "type": "page",
  "data": {
    "options": [
      {"label": "4", "value": 3},
      {"label": "5", "value": 5},
      {"label": "5.5", "value": 5.5},
      {"label": "6", "value": 6}
    ]
  },
  "body": [
    {
      "type": "crud",
      "syncLocation": false,
      "api": "/api/mock2/sample",
      "columns": [
          {
              "name": "id",
              "label": "ID"
          },
          {
              "name": "grade",
              "label": "CSS grade",
              "filterable": {
                "source": "/api/mock2/crud/filterOptions"
              }
          },
          {
              "name": "version",
              "label": "Version",
              "filterable": {
                "source": "${options}"
              }
          }
      ]
    }
  ]
}
```

### 快速编辑

可以通过给列配置：`"quickEdit":true`和`quickSaveApi` 可以实现表格内快速编辑并批量保存的功能。

如下`Rendering engine`列的每一行中，会生成可编辑图标，点击后会显示弹框，用于编辑该列的值，

```schema: scope="body"
{
    "type": "crud",
    "syncLocation": false,
    "api": "/api/mock2/sample",
    "quickSaveApi": "/api/mock2/sample/bulkUpdate",
    "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "engine",
            "label": "Rendering engine",
            "quickEdit":true
        }
    ]
}
```

#### 指定编辑表单项类型

`quickEdit`也可以配置对象形式，可以指定编辑表单项的类型，例如`"type": "select"`：

```schema: scope="body"
{
    "type": "crud",
    "syncLocation": false,
    "api": "/api/mock2/sample",
    "quickSaveApi": "/api/mock2/sample/bulkUpdate",
    "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "grade",
            "label": "CSS grade",
            "quickEdit": {
                "type": "select",
                "options": [
                    "A",
                    "B",
                    "C",
                    "D",
                    "X"
                ]
            }
        }
    ]
}
```

#### 快速编辑多个表单项

```schema: scope="body"
{
    "type": "crud",
    "syncLocation": false,
    "api": "/api/mock2/sample",
    "quickSaveApi": "/api/mock2/sample/bulkUpdate",
    "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "grade",
            "label": "CSS grade",
            "quickEdit": {
                "body": [
                    {
                        "type": "select",
                        "name": "grade",
                        "options": [
                            "A",
                            "B",
                            "C",
                            "D",
                            "X"
                        ]
                    },

                    {
                        "label": "id",
                        "type": "input-text",
                        "name": "id"
                    }
                ]
            }
        }
    ]
}
```

#### 内联模式

配置`quickEdit`的`mode`为`inline`。可以直接将编辑表单项渲染至表格内，可以直接操作编辑。

```schema: scope="body"
{
    "type": "crud",
    "syncLocation": false,
    "api": "/api/mock2/sample",
    "quickSaveApi": "/api/mock2/sample/bulkUpdate",
    "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "grade",
            "label": "CSS grade",
            "quickEdit": {
                "mode": "inline",
                "type": "select",
                "size": "xs",
                "options": [
                    "A",
                    "B",
                    "C",
                    "D",
                    "X"
                ]
            }
        },
        {
            "name": "switch",
            "label": "switch",
            "quickEdit": {
                "mode": "inline",
                "type": "switch",
                "onText": "开启",
                "offText": "关闭"
            }
        }
    ]
}
```

#### 即时保存

如果想编辑完表单项之后，不想点击顶部确认按钮来进行保存，而是即时保存当前标记的数据，则需要配置 `quickEdit` 中的 `"saveImmediately": true`，然后配置接口`quickSaveItemApi`，可以直接将编辑表单项渲染至表格内操作。

```schema: scope="body"
{
    "type": "crud",
    "syncLocation": false,
    "api": "/api/mock2/sample",
    "quickSaveItemApi": "/api/mock2/sample/$id",
    "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "grade",
            "label": "CSS grade",
            "quickEdit": {
                "mode": "inline",
                "type": "select",
                "size": "xs",
                "options": [
                    "A",
                    "B",
                    "C",
                    "D",
                    "X"
                ],
                "saveImmediately": true
            }
        },
        {
            "name": "switch",
            "label": "switch",
            "quickEdit": {
                "mode": "inline",
                "type": "switch",
                "onText": "开启",
                "offText": "关闭",
                "saveImmediately": true,
                "resetOnFailed": true
            }
        }
    ]
}
```

你也可以在`saveImmediately`中配置 api，实现即时保存

```schema: scope="body"
{
    "type": "crud",
    "syncLocation": false,
    "api": "/api/mock2/sample",
    "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "grade",
            "label": "CSS grade",
            "quickEdit": {
                "mode": "inline",
                "type": "select",
                "size": "xs",
                "options": [
                    "A",
                    "B",
                    "C",
                    "D",
                    "X"
                ],
                "saveImmediately": {
                    "api": "/api/mock2/sample/$id"
                }
            }
        },
        {
            "name": "grade",
            "label": "CSS grade",
            "quickEdit": {
                "mode": "inline",
                "type": "switch",
                "onText": "开启",
                "offText": "关闭",
                "saveImmediately": true
            }
        }
    ]
}
```

#### 配置快速编辑启动条件

通过 `quickEditEnabledOn` 配置表达式来实现，如下，只有 id 小于 5 的数据可以编辑 engine。

```schema: scope="body"
{
    "type": "crud",
    "syncLocation": false,
    "api": "/api/mock2/sample",
    "quickSaveApi": "/api/mock2/sample/bulkUpdate",
    "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "engine",
            "label": "Rendering engine",
            "quickEdit":true,
            "quickEditEnabledOn": "this.id < 5"
        }
    ]
}
```

## 顶部和底部工具栏

crud 组件支持通过配置`headerToolbar`和`footerToolbar`属性，实现在表格顶部和底部渲染组件，

```schema: scope="body"
{
    "type": "crud",
    "syncLocation": false,
    "api": "/api/mock2/sample",
    "headerToolbar": [
        {
            "type": "tpl",
            "tpl": "一共有${count}条数据"
        }
    ],
    "footerToolbar": [
        {
            "type": "action",
            "actionType": "dialog",
            "label": "底部工具栏按钮",
            "dialog": {
                "title": "一个弹框",
                "body": {
                    "type": "tpl",
                    "tpl": "一个简单的弹框"
                }
            }
        }
    ],
    "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "engine",
            "label": "Rendering engine"
        },
        {
            "name": "browser",
            "label": "Browser"
        },
        {
            "name": "platform",
            "label": "Platform(s)"
        },
        {
            "name": "version",
            "label": "Engine version"
        },
        {
            "name": "grade",
            "label": "CSS grade"
        }
    ]
}
```

上例中我们在顶部渲染了一段模板，通过`${count}`取到数据域中，CRUD 返回的`count`变量值；然后我们在底部渲染了一个按钮。

从上面一些例子中你可能已经发现，当我们不配置该属性时，crud 默认会在顶部和底部渲染一些组件，实际上，`headerToolbar`和`footerToolbar`默认会有下面这些配置：

```json
{
  "headerToolbar": ["bulkActions", "pagination"],
  "footerToolbar": ["statistics", "pagination"]
}
```

- 在顶部工具栏中：渲染批量操作按钮（如果在 crud 中，配置了 bulkActions 的话）和 分页组件
- 在底部工具栏中：渲染数据统计组件 和 分页组件

> 如果你不希望在顶部或者底部渲染默认组件，你可以设置`headerToolbar`和`footerToolbar`为空数组`[]`

这些组件还能设置 `align` 来控制位置，有 `left` 和 `right` 两种，比如

```json
{
  "headerToolbar": [
    {
      "type": "bulkActions",
      "align": "right"
    }
  ]
}
```

### 其它 amis 组件

在 `headerToolbar` 和 `footerToolbar` 中可以配置各种 amis 其它组件，比如按钮和 tpl：

```schema: scope="body"
{
    "type": "crud",
    "name": "myCRUD",
    "syncLocation": false,
    "api": "/api/mock2/sample",
    "headerToolbar": [
        {
            "label": "点击弹框",
            "type": "button",
            "actionType": "dialog",
            "icon": "fa fa-plus",
            "level": "primary",
            "dialog": {
                "title": "弹框标题",
                "body": "这是一个弹框"
            }
        },
        {
            "type": "tpl",
            "tpl": "自定义模板"
        },
        {
            "label": "",
            "icon": "fa fa-repeat",
            "type": "button",
            "actionType": "reload",
            "target": "myCRUD",
            "align": "right"
        }
    ],
    "footerToolbar": [],
    "columns": [
        {
            "name": "id",
            "label": "ID"
        }
    ]
}
```

### 分页

在`headerToolbar`或者`footerToolbar`数组中添加`pagination`字符串，并且在数据源接口中返回了数据总数`count`，即可以渲染分页组件；添加`switch-per-page`字符串，可以渲染切换每页条数组件

```schema: scope="body"
{
    "type": "crud",
    "syncLocation": false,
    "api": "/api/mock2/sample",
    "headerToolbar": [],
    "footerToolbar": ["switch-per-page", "pagination"],
    "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "grade",
            "label": "CSS grade",
            "quickEdit": {
                "mode": "inline",
                "type": "select",
                "size": "xs",
                "options": [
                    "A",
                    "B",
                    "C",
                    "D",
                    "X"
                ],
                "saveImmediately": {
                    "api": "/api/mock2/sample/$id"
                }
            }
        }
    ]
}
```

`crud`默认不会处理数据分页，只是会把分页参数传给后端，由后端实现分页，并返回需要展示的数据 和 总数据数`total`变量：

默认传给后端的分页参数格式为：

```json
{
  "page": 1,
  "perPage": 10
}
```

你可以通过配置`pageField`和`perPageField`来修改传给后端的分页数据格式，如：

```json
{
  "pageField": "pageNo",
  "perPageField": "pageSize"
}
```

这样传给后端的参数格式将为：

```json
{
  "pageNo": 1,
  "pageSize": 10
}
```

你可以通过[数据映射](../../docs/concepts/data-mapping)，在`api`中获取这些参数。

```json
{
    "type": "crud",
    "api": {
        "method": "get",
        "url": "xxxxxx",
        "data": {
            "pageNo": "${page}",
            "pageSize": "${perPage}",
            ... // 一些其他参数
        }
    }
}
```

分页有两种模式：

**1. 知道数据总数**

如果后端可以知道数据总数时，接口返回格式如下：

```json
{
  "status": 0,
  "msg": "",
  "data": {
    "items": [
      {
        // 每一行的数据。
        "id": 1,
        "xxx": "xxxx"
      }
    ],

    "total": 200 // 注意这里不是当前请求返回的 items 的长度，而是数据库一共有多少条数据，用于生成分页，
  }
}
```

该模式下，会自动计算总页码数，渲染出有页码的分页组件

**2. 不知道数据总数**

如果后端无法知道数据总数，那么可以返回`hasNext`字段，来标识是否有下一页。

```json
{
  "status": 0,
  "msg": "",
  "data": {
    "items": [
      {
        // 每个成员的数据。
        "id": 1,
        "xxx": "xxxx"
      }
    ],

    "hasNext": true // 标识是否有下一页。
  }
}
```

这样 amis 会在配置分页组件的地方，渲染出一个简单的页面跳转控件。

> 如果总数据只够展示一页，则默认不显示该分页组件

#### 前端分页

如果你的数据并不是很大，而且后端不方便做分页和条件过滤操作，那么通过配置`loadDataOnce`实现前端一次性加载并支持分页和条件过滤操作。

<div class="p-4 text-base text-gray-800 rounded-lg bg-gray-50" role="alert">
  <span class="font-medium text-gray-800 block">温馨提示</span>
  <span class="block">开启<code>loadDataOnce</code>后，搜索和过滤将交给组件处理，默认对所有字段采用模糊匹配（比如：<code>mi</code>将会匹配<code>amis</code>）。如果首次加载数据时设置了预设条件，导致接口返回的数据集合未按照此规则过滤，则可能导致切换页码后分页错误。此时有2种方案处理：</span>
  <span class="block" style="text-indent: 2em">1. 将接口返回的列表数据按照所有字段模糊匹配的规则处理</span>
  <span class="block" style="text-indent: 2em">2. 配置<a href="#匹配函数"><code>matchFunc</code></a>，自定义处理过滤</span>
</div>

```schema: scope="body"
{
    "type": "crud",
    "syncLocation": false,
    "api": "/api/mock2/sample",
    "loadDataOnce": true,
    "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "engine",
            "label": "Rendering engine"
        },
        {
            "name": "browser",
            "label": "Browser"
        },
        {
            "name": "platform",
            "label": "Platform(s)"
        },
        {
            "name": "version",
            "label": "Engine version"
        },
        {
            "name": "grade",
            "label": "CSS grade",
            "sortable": true
        }
    ]
}
```

配置一次性加载后，基本的分页、快速排序操作将会在前端进行完成。如果想实现前端检索(目前是模糊搜索)，可以在 table 的 `columns` 对应项配置 `searchable` 来实现。

```schema: scope="body"
{
    "type": "crud",
    "syncLocation": false,
    "api": "/api/mock2/sample",
    "loadDataOnce": true,
    "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "engine",
            "label": "Rendering engine"
        },
        {
            "name": "browser",
            "label": "Browser"
        },
        {
            "name": "platform",
            "label": "Platform(s)"
        },
        {
            "name": "version",
            "label": "Engine version",
            "searchable": {
                "type": "select",
                "name": "version",
                "label": "Engine version",
                "clearable": true,
                "multiple": true,
                "searchable": true,
                "checkAll": true,
                "options": ["1.7", "3.3", "5.6"],
                "maxTagCount": 10,
                "extractValue": true,
                "joinValues": false,
                "delimiter": ',',
                "defaultCheckAll": false,
                "checkAllLabel": "全选"
              }
        },
        {
            "name": "grade",
            "label": "CSS grade"
        }
    ]
}
```

> **注意：**如果你的数据量较大，请务必使用服务端分页的方案，过多的前端数据展示，会显著影响前端页面的性能

另外前端一次性加载当有查寻条件的时候，默认还是会重新请求一次，如果配置 `loadDataOnceFetchOnFilter` 为 `false` 则为前端过滤。

```schema: scope="body"
{
  "type": "crud",
  "syncLocation": false,
  "api": "/api/mock2/sample",
  "loadDataOnce": true,
  "loadDataOnceFetchOnFilter": false,
  "autoGenerateFilter": true,
  "columns": [
    {
      "name": "id",
      "label": "ID"
    },
    {
      "name": "engine",
      "label": "Rendering engine"
    },
    {
      "name": "browser",
      "label": "Browser"
    },
    {
      "name": "platform",
      "label": "Platform(s)"
    },
    {
      "name": "version",
      "label": "Engine version",
      "searchable": {
        "type": "select",
        "name": "version",
        "label": "Engine version",
        "clearable": true,
        "multiple": true,
        "searchable": true,
        "checkAll": true,
        "options": [
          "1.7",
          "3.3",
          "5.6"
        ],
        "maxTagCount": 10,
        "extractValue": true,
        "joinValues": false,
        "delimiter": ",",
        "defaultCheckAll": false,
        "checkAllLabel": "全选"
      }
    },
    {
      "name": "grade",
      "label": "CSS grade"
    }
  ]
}
```

`loadDataOnceFetchOnFilter` 配置成 `true` 则会强制重新请求接口比如以下用法

> 此时如果不配置或者配置为 `false` 是前端直接过滤，不过记得配置 name 为行数据中的属性，如果行数据中没有对应属性则不会起作用

```schema: scope="body"
{
  "type": "crud",
  "syncLocation": false,
  "api": "/api/mock2/sample",
  "loadDataOnce": true,
  "loadDataOnceFetchOnFilter": true,
  "headerToolbar": [
    {
      "type": "search-box",
      "name": "keywords"
    }
  ],
  "columns": [
    {
      "name": "id",
      "label": "ID"
    },
    {
      "name": "engine",
      "label": "Rendering engine"
    },
    {
      "name": "browser",
      "label": "Browser"
    },
    {
      "name": "platform",
      "label": "Platform(s)"
    },
    {
      "name": "version",
      "label": "Engine version",
      "searchable": {
        "type": "select",
        "name": "version",
        "label": "Engine version",
        "clearable": true,
        "multiple": true,
        "searchable": true,
        "checkAll": true,
        "options": [
          "1.7",
          "3.3",
          "5.6"
        ],
        "maxTagCount": 10,
        "extractValue": true,
        "joinValues": false,
        "delimiter": ",",
        "defaultCheckAll": false,
        "checkAllLabel": "全选"
      }
    },
    {
      "name": "grade",
      "label": "CSS grade"
    }
  ]
}
```

##### 匹配函数

> `3.5.0` 及以上版本

支持自定义匹配函数`matchFunc`，当开启`loadDataOnce`时，会基于该函数计算的匹配结果进行过滤，主要用于处理列字段类型较为复杂或者字段值格式和后端返回不一致的场景，函数签名如下：

```typescript
interface CRUDMatchFunc {
  (
    /* 当前列表的全量数据 */
    items: any,
    /* 最近一次接口返回的全量数据 */
    itemsRaw: any,
    /** 相关配置 */
    options?: {
      /* 查询参数 */
      query: Record<string, any>;
      /* 列配置 */
      columns: any;
      /** match-sorter 匹配函数 */
      matchSorter: (
        items: any[],
        value: string,
        options?: MatchSorterOptions<any>
      ) => any[];
    }
  ): boolean;
}
```

具体效果请参考[示例](../../../examples/crud/match-func)，从`3.6.0`版本开始，`options`中支持使用`matchSorter`函数处理复杂的过滤场景，比如前缀匹配、模糊匹配等，更多详细内容推荐查看[match-sorter](https://github.com/kentcdodds/match-sorter)。

### 显示序号

通过配置 `showIndex` 为 `true` 启用

```schema: scope="body"
{
    "type": "crud",
    "syncLocation": false,
    "api": "/api/mock2/sample",
    "loadDataOnce": true,
    "showIndex": true,
    "columns": [
        {
            "name": "engine",
            "label": "Rendering engine"
        },
        {
            "name": "browser",
            "label": "Browser"
        },
        {
            "name": "platform",
            "label": "Platform(s)"
        },
        {
            "name": "version",
            "label": "Engine version"
        },
        {
            "name": "grade",
            "label": "CSS grade",
            "sortable": true
        }
    ]
}
```

### 批量操作

在`headerToolbar`或者`footerToolbar`数组中添加`bulkActions`字符串，并且在 crud 上配置`bulkActions`行为按钮数组，可以实现选中表格项并批量操作的功能。

> 需要设置`primaryField`用于标识选中状态，配置当前行数据中的某一**唯一标识字段**，例如`id`，否则可能会出现无法选中的问题

```
/* Detailed source-code truncated for AI context efficiency. */
```

#### 批量操作数据域

批量操作会默认将下面数据添加到数据域中以供**按钮行为**使用，需要注意的是**静态**和**批量操作**时的数据域是不同的。**静态数据域**是指渲染批量操作区域时能够获取到的数据，**批量操作数据域**是指触发按钮动作时能够获取到的数据，具体区别参考下表：

| 属性名            | 类型                      | 所属数据域     | 说明                                                                                 | 版本    |
| ----------------- | ------------------------- | -------------- | ------------------------------------------------------------------------------------ | ------- |
| `currentPageData` | `Array<Column>`           | 静态, 批量操作 | 当前分页数据集合，`Column`为当前 Table 数据结构定义                                  | `2.4.0` |
| `selectedItems`   | `Array<Column>`           | 静态, 批量操作 | 选中的行数据集合                                                                     |
| `selectedIndexes` | `Array<string \| number>` | 静态, 批量操作 | 选中的行数据索引集合                                                                 |
| `unSelectedItems` | `Array<Column>`           | 静态, 批量操作 | 未选中的行数据集合                                                                   |
| `items`           | `Array<Column>`           | 批量操作       | `selectedItems` 的别名                                                               |
| `rows`            | `Array<Column>`           | 批量操作       | `selectedItems` 的别名，推荐用 `items`                                               |
| `ids`             | `string`                  | 批量操作       | 多个 id 值用英文逗号隔开，前提是行数据中有 id 字段，或者有指定的 `primaryField` 字段 |
| `event`           | `object`                  | 事件动作       | 可以通过`event.data`获取批量操作按钮上绑定的事件动作产生的数据                       |
| `...rest`         | `Record<string, any>`     | 批量操作       | 选中的行数据集合的首个元素的字段，注意列字段如果和以上字段重名时，会被上述字段值覆盖 |

你可以通过[数据映射](../../docs/concepts/data-mapping)，在`api`中获取这些参数。

**约束批量操作**

有时候并不是勾选了就能支持批量操作的，比如想约束如果勾选了某条数据 owner 值不是当前用户的就不可以操作。

有两种方式来约束。

1. 批量操作按钮上配置 `disabledOn` 值为 `this.selectedItems.some(item => item.owner === this.amisUser.name)`
2. 给表格加上 `itemCheckableOn` 值为 `this.owner === this.amisUser.name` 表示只有 owner 是自己的才可以打勾。

**保留条目选择**

默认分页、搜索后，用户选择条目会被清空，配置`keepItemSelectionOnPageChange`属性后会保留用户选择，可以实现跨页面批量操作。
同时可以通过配置`maxKeepItemSelectionLength`属性限制最大勾选数

```schema: scope="body"
{
  "type": "crud",
  "syncLocation": false,
  "api": "/api/mock2/sample",
  "headerToolbar": [
    "bulkActions"
  ],
  "keepItemSelectionOnPageChange": true,
  "maxKeepItemSelectionLength": 4,
  "bulkActions": [
    {
      "label": "批量删除",
      "actionType": "ajax",
      "api": "delete:/api/mock2/sample/${ids|raw}",
      "confirmText": "确定要批量删除?"
    },
    {
      "label": "批量修改",
      "actionType": "dialog",
      "dialog": {
        "title": "批量编辑",
        "body": {
          "type": "form",
          "api": "/api/mock2/sample/bulkUpdate2",
          "body": [
            {
              "type": "hidden",
              "name": "ids"
            },
            {
              "type": "input-text",
              "name": "engine",
              "label": "Engine"
            }
          ]
        }
      }
    }
  ],
  "columns": [
    {
      "name": "id",
      "label": "ID"
    },
    {
      "name": "engine",
      "label": "Rendering engine"
    },
    {
      "name": "browser",
      "label": "Browser"
    },
    {
      "name": "platform",
      "label": "Platform(s)"
    },
    {
      "name": "version",
      "label": "Engine version"
    },
    {
      "name": "grade",
      "label": "CSS grade"
    }
  ]
}
```

**当前页最大勾选数**

如果不需要在分页、搜索后，保留用户选择，即不需要配置`keepItemSelectionOnPageChange`，可以通过配置`maxItemSelectionLength`属性限制当前页条目的最大勾选数

```schema: scope="body"
{
  "type": "crud",
  "syncLocation": false,
  "api": "/api/mock2/sample",
  "headerToolbar": [
    "bulkActions"
  ],
  "maxItemSelectionLength": 4,
  "bulkActions": [
    {
      "label": "批量删除",
      "actionType": "ajax",
      "api": "delete:/api/mock2/sample/${ids|raw}",
      "confirmText": "确定要批量删除?"
    },
    {
      "label": "批量修改",
      "actionType": "dialog",
      "dialog": {
        "title": "批量编辑",
        "body": {
          "type": "form",
          "api": "/api/mock2/sample/bulkUpdate2",
          "body": [
            {
              "type": "hidden",
              "name": "ids"
            },
            {
              "type": "input-text",
              "name": "engine",
              "label": "Engine"
            }
          ]
        }
      }
    }
  ],
  "columns": [
    {
      "name": "id",
      "label": "ID"
    },
    {
      "name": "engine",
      "label": "Rendering engine"
    },
    {
      "name": "browser",
      "label": "Browser"
    },
    {
      "name": "platform",
      "label": "Platform(s)"
    },
    {
      "name": "version",
      "label": "Engine version"
    },
    {
      "name": "grade",
      "label": "CSS grade"
    }
  ],
  "itemCheckableOn": "this.index !== 2"
}
```

`maxItemSelectionLength`也可以和`keepItemSelectionOnPageChange`搭配使用，起到和`maxKeepItemSelectionLength`一样的效果

```schema: scope="body"
{
  "type": "crud",
  "syncLocation": false,
  "api": "/api/mock2/sample",
  "headerToolbar": [
    "bulkActions"
  ],
  "keepItemSelectionOnPageChange": true,
  "maxItemSelectionLength": 4,
  "bulkActions": [
    {
      "label": "批量删除",
      "actionType": "ajax",
      "api": "delete:/api/mock2/sample/${ids|raw}",
      "confirmText": "确定要批量删除?"
    },
    {
      "label": "批量修改",
      "actionType": "dialog",
      "dialog": {
        "title": "批量编辑",
        "body": {
          "type": "form",
          "api": "/api/mock2/sample/bulkUpdate2",
          "body": [
            {
              "type": "hidden",
              "name": "ids"
            },
            {
              "type": "input-text",
              "name": "engine",
              "label": "Engine"
            }
          ]
        }
      }
    }
  ],
  "columns": [
    {
      "name": "id",
      "label": "ID"
    },
    {
      "name": "engine",
      "label": "Rendering engine"
    },
    {
      "name": "browser",
      "label": "Browser"
    },
    {
      "name": "platform",
      "label": "Platform(s)"
    },
    {
      "name": "version",
      "label": "Engine version"
    },
    {
      "name": "grade",
      "label": "CSS grade"
    }
  ],
  "itemCheckableOn": "this.index !== 2 && this.index !== 5"
}
```

还可以设置 `"checkOnItemClick": true` 属性来支持点击一行的触发选中状态切换

```
/* Detailed source-code truncated for AI context efficiency. */
```

### 悬浮操作栏

通过配置 `itemActions` 可以启用悬浮操作栏，鼠标悬停到行上，右侧会出现对应的操作按钮。

```schema: scope="body"
{
    "type": "crud",
    "syncLocation": false,
    "api": "/api/mock2/sample",
    "checkOnItemClick": true,
    "itemActions": [
        {
          "type": "button",
          "label": "按钮 1",
          "actionType": "toast",
          "toast": {
            "items": [
              {
                "level": "info",
                "body": "${&|json}"
              }
            ]
          }
        },
        {
          "type": "button",
          "label": "按钮 2",
          "actionType": "toast",
          "toast": {
            "items": [
              {
                "level": "info",
                "body": "${&|json}"
              }
            ]
          }
        }
    ],
    "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "engine",
            "label": "Rendering engine"
        },
        {
            "name": "browser",
            "label": "Browser"
        },
        {
            "name": "platform",
            "label": "Platform(s)"
        },
        {
            "name": "version",
            "label": "Engine version"
        },
        {
            "name": "grade",
            "label": "CSS grade"
        }
    ]
}
```

当同时配置 `itemActions` 和 `bulkActions`, 顶部工具栏会根据选择的条数来切换显示按钮。

```
/* Detailed source-code truncated for AI context efficiency. */
```

如果同时启用时，只想把按钮展示在顶部，而不是悬浮，则需要给按钮上配置 `hiddenOnHover`。

```
/* Detailed source-code truncated for AI context efficiency. */
```

### 数据统计

在`headerToolbar`或者`footerToolbar`数组中添加`statistics`字符串，可以实现简单的数据统计功能

```schema: scope="body"
{
    "type": "crud",
    "syncLocation": false,
    "api": "/api/mock2/sample",
    "headerToolbar": ["statistics"],
    "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "engine",
            "label": "Rendering engine"
        },
        {
            "name": "browser",
            "label": "Browser"
        },
        {
            "name": "platform",
            "label": "Platform(s)"
        },
        {
            "name": "version",
            "label": "Engine version"
        },
        {
            "name": "grade",
            "label": "CSS grade"
        }
    ]
}
```

### 加载更多

在`headerToolbar`或者`footerToolbar`数组中添加`load-more`字符串，可以实现点击加载更多功能。

```schema: scope="body"
{
    "type": "crud",
    "syncLocation": false,
    "api": "/api/mock2/sample",
    "headerToolbar": ["load-more"],
    "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "engine",
            "label": "Rendering engine"
        },
        {
            "name": "browser",
            "label": "Browser"
        },
        {
            "name": "platform",
            "label": "Platform(s)"
        },
        {
            "name": "version",
            "label": "Engine version"
        },
        {
            "name": "grade",
            "label": "CSS grade"
        }
    ]
}
```

### 导出 CSV

在`headerToolbar`或者`footerToolbar`数组中添加`export-csv`字符串，可以实现点击下载 CSV 的功能，注意这里只包括当前分页的数据，要下载全部数据需要通过后端 API 实现。

> 注意：导出 CSV 时，默认使用 CRUD 的接口数据，不导出「操作」列

```schema: scope="body"
{
    "type": "crud",
    "syncLocation": false,
    "api": "/api/mock2/sample",
    "headerToolbar": ["export-csv"],
    "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "engine",
            "label": "Rendering engine"
        },
        {
            "name": "browser",
            "label": "Browser"
        },
        {
            "name": "platform",
            "label": "Platform(s)"
        },
        {
            "name": "version",
            "label": "Engine version"
        },
        {
            "name": "grade",
            "label": "CSS grade",
            "type": "mapping",
            "map": {
                "*": "<span class=\"label label-info\">${grade}</span>"
            }
        }
    ]
}
```

#### 通过 api 导出 CSV

> 1.4.0 及以上版本

`export-csv` 可以单独配置 `api` 实现导出全量功能，这个 api 的返回结果和 CRUD 类似

```schema: scope="body"
{
    "type": "crud",
    "syncLocation": false,
    "api": "/api/mock2/sample",
    "headerToolbar": [
        {
            "type": "export-csv",
            "label": "全量导出 CSV",
            "api": "/api/mock2/sample"
        }
    ],
    "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "engine",
            "label": "Rendering engine"
        },
        {
            "name": "browser",
            "label": "Browser"
        },
        {
            "name": "platform",
            "label": "Platform(s)"
        },
        {
            "name": "version",
            "label": "Engine version"
        },
        {
            "name": "grade",
            "label": "CSS grade",
            "type": "mapping",
            "map": {
                "*": "<span class=\"label label-info\">${grade}</span>"
            }
        }
    ]
}
```

#### 自定义导出 CSV 的文件名

> 1.4.0 及以上版本

`export-csv` 可以单独配置 `api` 实现导出全量功能，这个 api 的返回结果和 CRUD 类似

```schema: scope="body"
{
    "type": "crud",
    "syncLocation": false,
    "api": "/api/mock2/sample",
    "data": {
        "name": "123"
    },
    "headerToolbar": [
        {
            "type": "export-csv",
            "label": "自定义导出 CSV",
            "api": "/api/mock2/sample",
            "filename": "自定义文件名${name}"
        }
    ],
    "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "engine",
            "label": "Rendering engine"
        },
        {
            "name": "browser",
            "label": "Browser"
        },
        {
            "name": "platform",
            "label": "Platform(s)"
        },
        {
            "name": "version",
            "label": "Engine version"
        },
        {
            "name": "grade",
            "label": "CSS grade",
            "type": "mapping",
            "map": {
                "*": "<span class=\"label label-info\">${grade}</span>"
            }
        }
    ]
}
```

### 导出 Excel

在`headerToolbar`或者`footerToolbar`数组中添加`export-excel`字符串，可以实现点击下载 Excel 的功能，和导出 CSV 一样只包括当前分页的数据，但它们有明显区别：

1. 导出 CSV 是将 api 返回数据导出，表头是数据里的 key，而 Excel 的表头使用的是 label。
2. 导出 Excel 更重视展现一致，支持合并单元格、链接、mapping 映射、图片（需要加[跨域 Header](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)）。
3. 导出 Excel 只在 `mode` 为 `table` 时能用。

> 注意：导出 Excel 时，默认不导出「操作」列

```schema: scope="body"
{
    "type": "crud",
    "syncLocation": false,
    "api": "/api/mock2/sample",
    "headerToolbar": ["export-excel"],
    "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "engine",
            "label": "Rendering engine"
        },
        {
            "name": "browser",
            "label": "Browser"
        },
        {
            "name": "platform",
            "label": "Platform(s)"
        },
        {
            "name": "version",
            "label": "Engine version"
        },
        {
            "name": "grade",
            "label": "CSS grade",
            "type": "mapping",
            "map": {
                "*": "<span class=\"label label-info\">${grade}</span>"
            }
        }
    ]
}
```

#### 只导出部分列

> 1.4.0 及以上版本

通过配置 `columns` 来支持只导出部分列，其中是需要导出的列 `name` 数组

```schema: scope="body"
{
    "type": "crud",
    "syncLocation": false,
    "api": "/api/mock2/sample",
    "headerToolbar": [{
        "type": "export-excel",
        "label": "只导出 engine 和  browser 列",
        "columns": ["engine", "browser"]
    }],
    "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "engine",
            "label": "Rendering engine"
        },
        {
            "name": "browser",
            "label": "Browser"
        },
        {
            "name": "platform",
            "label": "Platform(s)"
        },
        {
            "name": "version",
            "label": "Engine version"
        },
        {
            "name": "grade",
            "label": "CSS grade"
        }
    ]
}
```

> 1.8.0 及以上版本

`columns` 支持变量，可以从上下文取数组

```schema
{
    "type": "page",
    "data": {
        "columns": ["engine", "browser"]
    },
    "body": {
        "type": "crud",
        "syncLocation": false,
        "api": "/api/mock2/sample",
        "headerToolbar": [{
            "type": "export-excel",
            "label": "只导出 engine 和  browser 列",
            "columns": "${columns}"
        }],
        "columns": [
            {
                "name": "id",
                "label": "ID"
            },
            {
                "name": "engine",
                "label": "Rendering engine"
            },
            {
                "name": "browser",
                "label": "Browser"
            },
            {
                "name": "platform",
                "label": "Platform(s)"
            },
            {
                "name": "version",
                "label": "Engine version"
            },
            {
                "name": "grade",
                "label": "CSS grade"
            }
        ]
    }
}
```

#### 自定义导出列

> 1.8.0 及以上版本

除了简单隐藏某些列，还可以通过 `exportColumns` 完全控制导出列，比如新增某些列，它的配置项和 `columns` 一致

```schema: scope="body"
{
    "type": "crud",
    "syncLocation": false,
    "api": "/api/mock2/sample",
    "headerToolbar": [{
        "type": "export-excel",
        "label": "导出 Excel",
        "exportColumns": [
            {
                "name": "engine",
                "label": "Engine"
            },
            {
                "type": "tpl",
                "label": "tpl",
                "tpl": "${browser}"
            }
        ]
    }],
    "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "engine",
            "label": "Rendering engine"
        },
        {
            "name": "browser",
            "label": "Browser"
        },
        {
            "name": "platform",
            "label": "Platform(s)"
        },
        {
            "name": "version",
            "label": "Engine version"
        },
        {
            "name": "grade",
            "label": "CSS grade"
        }
    ]
}
```

#### 指定导出行

> 3.2.0 及以上版本

可以通过配置 `rowSlice` 属性来控制导出哪些行

```schema: scope="body"
{
    "type": "crud",
    "syncLocation": false,
    "api": "/api/mock2/sample",
    "headerToolbar": [{
        "type": "export-excel",
        "label": "导出 1, 4, 5 行",
        "rowSlice": "0,3:5"
    }],
    "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "engine",
            "label": "Rendering engine"
        },
        {
            "name": "browser",
            "label": "Browser"
        },
        {
            "name": "platform",
            "label": "Platform(s)"
        },
        {
            "name": "version",
            "label": "Engine version"
        },
        {
            "name": "grade",
            "label": "CSS grade"
        }
    ]
}
```

`rowSlice` 支持以下写法

- 取单个值 '1,2,3'，代表取 1、2、3 索引的内容
- 取范围 '3:10'，代表取 3-9 索引的内容
  - ':' 代表所有行
  - '1:' 代表从第二行开始到结束
  - 结束可以是负数 ':-1'，代表除了最后一个元素的所有元素，开始为空代表 0
- 前两种的组合 '1,3:10'，代表取 1 索引和 3-9 索引的内容

#### 通过 api 导出 Excel

> 1.1.6 以上版本支持

除了前面的用法，还可以配置 api 来通过数据请求来导出 Excel，实现类似全量导出的功能

```schema: scope="body"
{
    "type": "crud",
    "syncLocation": false,
    "headerToolbar": [{
        "type": "export-excel",
        "label": "全量导出 Excel",
        "api": "/api/mock2/sample"
    }],
    "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "engine",
            "label": "Rendering engine"
        },
        {
            "name": "browser",
            "label": "Browser"
        },
        {
            "name": "platform",
            "label": "Platform(s)"
        },
        {
            "name": "version",
            "label": "Engine version"
        },
        {
            "name": "grade",
            "label": "CSS grade"
        }
    ]
}
```

#### 自定义导出 Excel 的文件名

> 1.1.7 以上版本支持

通过 filename 自定义导出文件名（支持模板变量）

```schema: scope="body"
{
    "type": "crud",
    "syncLocation": false,
    "headerToolbar": [{
        "type": "export-excel",
        "label": "自定义导出 Excel",
        "filename": "自定义文件名${test}",
        "api": "/api/mock2/sample"
    }],
    "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "engine",
            "label": "Rendering engine"
        },
        {
            "name": "browser",
            "label": "Browser"
        },
        {
            "name": "platform",
            "label": "Platform(s)"
        },
        {
            "name": "version",
            "label": "Engine version"
        },
        {
            "name": "grade",
            "label": "CSS grade"
        }
    ]
}
```

### 导出 Excel 模板

> 6.1 及以上版本

配置是 `export-excel-template` 和前面 `export-excel` 不同，这个功能只导出表头，主要用于线下填数据，可以配合 input-excel 组件来上传填好的内容。

```schema: scope="body"
{
    "type": "crud",
    "syncLocation": false,
    "headerToolbar": [{
        "type": "export-excel-template",
        "label": "导出 Excel 模板",
    }],
    "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "engine",
            "label": "Rendering engine"
        },
        {
            "name": "browser",
            "label": "Browser"
        },
        {
            "name": "platform",
            "label": "Platform(s)"
        },
        {
            "name": "version",
            "label": "Engine version"
        },
        {
            "name": "grade",
            "label": "CSS grade"
        }
    ]
}
```

### 显隐显示查询条件表单

在`headerToolbar`或者`footerToolbar`数组中添加`filter-toggler`字符串，并且在 crud 中配置`"filterTogglable": true`后，可以渲染一个可以切换显示查询表单的功能按钮

```schema: scope="body"
{
    "type": "crud",
    "syncLocation": false,
    "api": "/api/mock2/sample",
     "filter": {
        "title": "条件搜索",
        "body": [
            {
                "type": "input-text",
                "name": "keywords",
                "placeholder": "通过关键字搜索"
            }
        ]
    },
    "filterTogglable": true,
    "headerToolbar": [
        "filter-toggler"
    ],
    "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "engine",
            "label": "Rendering engine"
        },
        {
            "name": "browser",
            "label": "Browser"
        },
        {
            "name": "platform",
            "label": "Platform(s)"
        },
        {
            "name": "version",
            "label": "Engine version"
        },
        {
            "name": "grade",
            "label": "CSS grade"
        }
    ]
}
```

还可以定制文案和按钮如：

```schema: scope="body"
{
    "type": "crud",
    "syncLocation": false,
    "api": "/api/mock2/sample",
     "filter": {
        "title": "条件搜索",
        "body": [
            {
                "type": "input-text",
                "name": "keywords",
                "placeholder": "通过关键字搜索"
            }
        ]
    },
    "filterTogglable": {
        "label": "更多搜索",
        "activeLabel": "收起搜索",
        "icon": "fa fa-arrow-down mr-1",
        "activeIcon": "fa fa-arrow-up mr-1"
    },
    "headerToolbar": [
        "filter-toggler"
    ],
    "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "engine",
            "label": "Rendering engine"
        },
        {
            "name": "browser",
            "label": "Browser"
        },
        {
            "name": "platform",
            "label": "Platform(s)"
        },
        {
            "name": "version",
            "label": "Engine version"
        },
        {
            "name": "grade",
            "label": "CSS grade"
        }
    ]
}
```

### 刷新按钮

> 1.5.0 及以上版本

可以通过 `reload` 来展现刷新按钮

```schema: scope="body"
{
    "type": "crud",
    "syncLocation": false,
    "api": "/api/mock2/sample",
    "headerToolbar": [
        "reload"
    ],
    "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "engine",
            "label": "Rendering engine"
        },
        {
            "name": "browser",
            "label": "Browser"
        },
        {
            "name": "platform",
            "label": "Platform(s)"
        },
        {
            "name": "version",
            "label": "Engine version"
        },
        {
            "name": "grade",
            "label": "CSS grade"
        }
    ]
}
```

它其实是个简化的 `button` 组件，可以参考 `button` 组件的文档做调整。

#### 刷新 CRUD 触发方式

触发 CRUD 刷新的方式有 3 种：

1. **reload 类型按钮**：使用`{"type": "reload", ...}`，CRUD 内部会对点击事件做处理
2. **reload 动作按钮**：使用`{"type": "action", "actionType": "reload", "target": "targetName", ...}`，指定`target`为要刷新的 CRUD 组件的`name`
3. **reload 事件动作**：使用[事件动作](../../docs/concepts/event-action)，指定`id`为要刷新的 CRUD 组件的`id`

```
/* Detailed source-code truncated for AI context efficiency. */
```

刷新后默认会重置当前已选行数据，即使设置了 `keepItemSelectionOnPageChange` 为 `true`，也会重置。

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 总结行

如果是默认的表格模式，还支持增加总结行，具体请参考 [table](./table#总结行) 的文档。

## 弹框与数据链

一般 CRUD 中会有弹框，然后进行数据展示或进行二次编辑的需求，通过在列中配置按钮，然后配置弹框，弹框内配置相应的组件即可。

现在问题是，如何获取到当前操作行的数据呢？

实际上，你操作当前行数据，会成为弹框这层节点的父级节点，因此你可以通过 [数据链](../../docs/concepts/datascope-and-datachain)，获取到上层，也就是点击的行的数据，具体获取方法和普通组件获取数据域中数据的方法相同，

```schema: scope="body"
{
  "type": "crud",
  "syncLocation": false,
  "api": "/api/mock2/sample",
  "draggable": true,
  "columns": [
    {
      "name": "id",
      "label": "ID"
    },
    {
      "name": "engine",
      "label": "Rendering engine"
    },
    {
      "name": "browser",
      "label": "Browser"
    },
    {
      "name": "platform",
      "label": "Platform(s)"
    },
    {
      "name": "version",
      "label": "Engine version"
    },
    {
      "name": "grade",
      "label": "CSS grade"
    },
    {
      "type": "button",
      "label": "一个弹框",
      "actionType": "dialog",
      "dialog": {
        "title": "一个弹框",
        "body": [
          {
            "type": "tpl",
            "tpl": "行数据中 Browser 值为：${browser}"
          },
          {
            "type": "divider"
          },
          {
            "type": "form",
            "api": "/api/mock2/sample/$id",
            "body": [
              {
                "type": "input-text",
                "name": "engine",
                "label": "Engine"
              }
            ]
          }
        ]
      }
    }
  ]
}
```

例如上例中 Tpl 用 `${browser}` 获取 `browser` 变量，Form 中配置`"name": "engine"` 映射 `engine` 变量。

> 遇到数据字段冲突时，可以在 [弹框上通过配置数据映射](./dialog#%E5%BC%B9%E6%A1%86%E4%B8%8E%E6%95%B0%E6%8D%AE%E6%98%A0%E5%B0%84) 解决。

## 拖拽排序

通过配置`"draggable": true`和保存排序接口`saveOrderApi`，可以实现拖拽排序功能，

```schema: scope="body"
{
    "type": "crud",
    "syncLocation": false,
    "api": "/api/mock2/sample",
    "draggable": true,
    "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "engine",
            "label": "Rendering engine"
        },
        {
            "name": "browser",
            "label": "Browser"
        },
        {
            "name": "platform",
            "label": "Platform(s)"
        },
        {
            "name": "version",
            "label": "Engine version"
        },
        {
            "name": "grade",
            "label": "CSS grade"
        }
    ]
}
```

同样的，前端是不会处理排序结果，需要后端调用接口`saveOrderApi`来保存新的顺序

发送方式默认为`POST`，会包含以下信息。

- `ids` 字符串如： `2,3,1,4,5,6` 用 id 来记录新的顺序。 前提是你的列表接口返回了 id 字段。另外如果你的 primaryField 不是 `id`，则需要配置如： `primaryField: "order_id"`。注意：无论你配置成什么 primayField，这个字段名始终是 ids。
- `rows` `Array<Item>` 数组格式，新的顺序，数组里面包含所有原始信息。
- `insertAfter` 或者 `insertBefore` 这是 amis 生成的 diff 信息，对象格式，key 为目标成员的 primaryField 值，即 id，value 为数组，数组中存放成员 primaryField 值。如：

  ```json
  {
    "insertAfter": {
      "2": ["1", "3"],
      "6": ["4", "5"]
    }
  }
  ```

  表示：成员 1 和成员 3 插入到了成员 2 的后面。成员 4 和 成员 5 插入到了 成员 6 的后面。

你可以通过[数据映射](../../docs/concepts/data-mapping)，在`api`中获取这些参数。

如下:

```json
{
  "saveOrderApi": {
    "url": "/api/xxxx",
    "data": {
      "ids": "${ids}"
    }
  }
}
```

这样就只会发送 ids 了。

### 列排序

通过配置`headerToolbar` 中 `columns-toggler` 的 `"draggable": true`可以实现设置显示列和列排序功能。

```schema: scope="body"
{
    "type": "crud",
    "api": "/api/mock2/sample",
    "syncLocation": false,
    "headerToolbar": [
        {
            "type": "columns-toggler",
            "align": "right",
            "draggable": true,
            "icon": "fas fa-cog",
            "overlay": true,
            "footerBtnSize": "sm"
        }
    ],
    "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "engine",
            "label": "Rendering engine"
        },
        {
            "name": "browser",
            "label": "Browser"
        },
        {
            "name": "platform",
            "label": "Platform(s)"
        },
        {
            "name": "version",
            "label": "Engine version"
        },
        {
            "name": "grade",
            "label": "CSS grade"
        }
    ]
}
```

## 单条操作

当操作对象是单条数据时这类操作叫单条操作，比如：编辑、删除、通过、拒绝等等。CRUD 的 table 模式可以在 column 通过放置按钮来完成（其他模式参考 table 模式）。比如编辑就是添加个按钮行为是弹框类型的按钮或者添加一个页面跳转类型的按钮把当前行数据的 id 放在 query 中传过去、删除操作就是配置一个按钮行为是 AJAX 类型的按钮，将数据通过 api 发送给后端完成。

CRUD 中不限制有多少个单条操作、添加一个操作对应的添加一个按钮就行了。CRUD 在处理按钮行为的时候会把当前行的完整数据传递过去，如果你的按钮行为是弹出时，还会包含一下信息：

- `hasNext` `boolean` 当按钮行为是弹框时，还会携带这个数据可以用来判断当前页中是否有下一条数据。
- `hasPrev` `boolean` 当按钮行为是弹框时，还会携带这个数据可以判断用来当前页中是否有上一条数据。
- `index` `number` 当按钮行为是弹框时，还会携带这个数据可以用来获取当前行数据在这一页中的位置。
- `prevIndex` `number`
- `nextIndex` `number`

你可以通过[数据映射](../../docs/concepts/data-mapping)，在`api`中获取这些参数。

如果你的按钮类型是 ajax，你也可以限定只发送部分数据比如。

```json
{
  "type": "button",
  "label": "删除",
  "actionType": "ajax",
  "api": "delete:/api/xxxx/$id",
  "confirmText": "确定要删除？"
}
```

上面这个例子就会发送 id 字段了，如果想要全部发送过去同时还想添加点别的字段就这样：

```json
{
  "type": "button",
  "label": "删除",
  "actionType": "ajax",
  "api": {
    "method": "post",
    "url": "/api/xxxx/$id",
    "data": {
      "&": "$$",
      "op": "delete"
    }
  },
  "confirmText": "确定要删除？"
}
```

> **注意：** 如果使用`feedback`弹窗，如果不想关闭弹窗时触发`crud`再次拉取数据，需要设置`button`的`"reload":"none"`

## 过滤条件参数同步地址栏

默认 CRUD 会将过滤条件参数同步至浏览器地址栏中，比如搜索条件、当前页数，这也做的目的是刷新页面的时候还能进入之前的分页。

但也会导致地址栏中的参数数据合并到顶层的数据链中，例如：自动给同名的表单项设置默认值。如果不希望这个功能，可以设置 `syncLocation: false` 来关闭。

> 本文中的例子为了不相互影响都关闭了这个功能。
> 另外如果需要使用接口联动，需要设置`syncLocation: false`

`syncLocation`开启后，数据域经过地址栏同步后，原始值被转化为字符串同步回数据域，但布尔值（boolean）同步后不符合预期数据结构，导致组件渲染出错。比如查询条件表单中包含[Checkbox](./form/checkbox)组件，此时可以设置`{"trueValue": "1", "falseValue": "0"}`，将真值和假值设置为字符串格式规避。从`3.5.0`版本开始，已经支持[`parsePrimitiveQuery`](#解析query原始类型)，该配置默认开启。

## 动态列

> since 1.1.6

在 1.1.6 之前的版本，只能通过 service + schemaApi 让后端返回 schema 配置来实现，1.1.6 版本之后可以直接通过 crud 的数据接口返回了。
用这种方式可以简化动态列的实现，与 items 并列返回 columns 数组即即可。

```schema: scope="body"
{
    "type": "crud",
    "api": "/api/crud/dynamic?waitSeconds=1"
}
```

## 使用数据链中的数据

可以通过 `source` 属性来自定义去返回数据的字段，或者取数据域中的数据，比如

```schema
{
  "type": "page",
  "data": {
    "myItems": [
      {
        "id": 1
      }
    ]
  },
  "body": {
    "type": "crud",
    "source": "${myItems}",
    "columns": [
      {
        "name": "id",
        "label": "ID"
      }
    ]
  }
}
```

## 自定义点击行的行为

> 1.4.0 及以上版本

配置 `itemAction` 可以实现点击某一行后进行自定义操作，支持 [action](./action) 里的所有配置，比如弹框、刷新其它组件等。

```schema: scope="body"
{
    "type": "crud",
    "api": "/api/mock2/sample",
    "syncLocation": false,
    "itemAction": {
      "type": "button",
      "actionType": "dialog",
      "dialog": {
        "title": "详情",
        "body": "当前行的数据 browser: ${browser}, version: ${version}"
      }
    },
    "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "engine",
            "label": "Rendering engine"
        },
        {
            "name": "browser",
            "label": "Browser"
        },
        {
            "name": "platform",
            "label": "Platform(s)"
        },
        {
            "name": "version",
            "label": "Engine version"
        },
        {
            "name": "grade",
            "label": "CSS grade"
        }
    ]
}
```

注意这个属性和 `checkOnItemClick` 冲突，因为都是定义行的点击行为，开启 `itemAction` 后 `checkOnItemClick` 将会失效。

> 1.4.2 及以上版本

itemAction 里的 onClick 还能通过 `data` 参数拿到当前行的数据，方便进行下一步操作

```schema: scope="body"
{
    "type": "crud",
    "api": "/api/mock2/sample",
    "syncLocation": false,
    "itemAction": {
      "type": "button",
      "onClick": "console.log(data); alert(data.engine)"
    },
    "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "engine",
            "label": "Rendering engine"
        },
        {
            "name": "browser",
            "label": "Browser"
        },
        {
            "name": "platform",
            "label": "Platform(s)"
        },
        {
            "name": "version",
            "label": "Engine version"
        },
        {
            "name": "grade",
            "label": "CSS grade"
        }
    ]
}
```

## 开启点选

当配置了 `bulkActions` 后，CRUD 会自动变成可点选状态。如果想直接开启可点选，可以配置 `selectable`，同时可以配置 `multiple` 来配置是单选还是多选。但是这个时候没有任何交互，需要配置事件动作，或者在工具栏中添加行为按钮完成交互逻辑。

```schema: scope="body"
{
    "type": "crud",
    "api": "/api/mock2/sample",
    "syncLocation": false,
    "selectable": true,
    "headerToolbar": [
      {
        "type": "button",
        "label": "按钮",
        "visibleOn": "${selectedItems.length}",
        "actionType": "toast",
        "toast": {
          "items": [
            {
              "level": "info",
              "body": "${selectedItems|json}"
            }
          ]
        }
      }
    ],
    "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "engine",
            "label": "Rendering engine"
        },
        {
            "name": "browser",
            "label": "Browser"
        },
        {
            "name": "platform",
            "label": "Platform(s)"
        },
        {
            "name": "version",
            "label": "Engine version"
        },
        {
            "name": "grade",
            "label": "CSS grade"
        }
    ]
}
```

多选场景且支持跨页面选择同时支持快速修改

```schema: scope="body"
{
  "type": "crud",
  "api": "/api/mock2/sample",
  "syncLocation": false,
  "loadDataOnce": true,
  "keepItemSelectionOnPageChange": true,
  "onEvent": {
    "selectedChange": {
      "actions": [
        {
          "actionType": "toast",
          "args": {
            "msg": "已选择数据 ${selectedItems.length} <br /> 未选 ${event.data.unSelectedItems.length} 条 <br /> 已选 indexes ${ENCODEJSON(selectedIndexes)}"
          }
        }
      ]
    }
  },
  "bulkActions": [
    {
      "label": "Button(${selectedItems.length})",
      "type": "button",
      "onEvent": {
        "click": {
          "actions": [
            {
              "actionType": "toast",
              "args": {
                "msg": "已选择数据 ${ENCODEJSON(ARRAYMAP(selectedItems, item => `${item.id}: ${item.engine}`))} <br /> 未选 ${event.data.unSelectedItems.length} 条 <br /> 已选 indexes ${ENCODEJSON(selectedIndexes)}"
              }
            }
          ]
        }
      }
    }
  ],
  "columns": [
    {
      "name": "id",
      "label": "ID"
    },
    {
      "name": "engine",
      "label": "Rendering engine",
      "quickEdit": true
    },
    {
      "name": "browser",
      "label": "Browser"
    },
    {
      "name": "platform",
      "label": "Platform(s)"
    },
    {
      "name": "version",
      "label": "Engine version"
    },
    {
      "name": "grade",
      "label": "CSS grade"
    }
  ]
}
```

## 属性表

| 属性名                                | 类型                                                                                    | 默认值                          | 说明                                                                                                                                           | 版本    |
| ------------------------------------- | --------------------------------------------------------------------------------------- | ------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
| type                                  | `string`                                                                                |                                 | `type` 指定为 CRUD 渲染器                                                                                                                      |
| mode                                  | `string`                                                                                | `"table"`                       | `"table" 、 "cards" 或者 "list"`                                                                                                               |
| title                                 | `string`                                                                                | `""`                            | 可设置成空，当设置成空时，没有标题栏                                                                                                           |
| className                             | `string`                                                                                |                                 | 表格外层 Dom 的类名                                                                                                                            |
| api                                   | [API](../../docs/types/api)                                                             |                                 | CRUD 用来获取列表数据的 api。                                                                                                                  |
| deferApi                              | [API](../../docs/types/api)                                                             |                                 | 当行数据中有 defer 属性时，用此接口进一步加载内容                                                                                              |
| loadDataOnce                          | `boolean`                                                                               |                                 | 是否一次性加载所有数据（前端分页）                                                                                                             |
| loadDataOnceFetchOnFilter             | `boolean`                                                                               | `true`                          | 在开启 loadDataOnce 时，filter 时是否去重新请求 api                                                                                            |
| source                                | `string`                                                                                |                                 | 数据映射接口返回某字段的值，不设置会默认使用接口返回的`${items}`或者`${rows}`，也可以设置成上层数据源的内容                                    |
| filter                                | [Form](./form/index)                                                                    |                                 | 设置过滤器，当该表单提交后，会把数据带给当前 `mode` 刷新列表。                                                                                 |
| filterTogglable                       | `boolean` \| `{label: string; icon: string; activeLabel: string; activeIcon?: string;}` | `false`                         | 是否可显隐过滤器                                                                                                                               |
| filterDefaultVisible                  | `boolean`                                                                               | `true`                          | 设置过滤器默认是否可见。                                                                                                                       |
| initFetch                             | `boolean`                                                                               | `true`                          | 是否初始化的时候拉取数据, 只针对有 filter 的情况, 没有 filter 初始都会拉取数据                                                                 |
| interval                              | `number`                                                                                | `3000`                          | 刷新时间(最低 1000)                                                                                                                            |
| silentPolling                         | `boolean`                                                                               | `false`                         | 配置刷新时是否隐藏加载动画                                                                                                                     |
| stopAutoRefreshWhen                   | `string`                                                                                | `""`                            | 通过[表达式](../../docs/concepts/expression)来配置停止刷新的条件                                                                               |
| stopAutoRefreshWhenModalIsOpen        | `boolean`                                                                               | `false`                         | 当有弹框时关闭自动刷新，关闭弹框又恢复                                                                                                         |
| syncLocation                          | `boolean`                                                                               | `true`                          | 是否将过滤条件的参数同步到地址栏                                                                                                               |
| draggable                             | `boolean`                                                                               | `false`                         | 是否可通过拖拽排序                                                                                                                             |
| resizable                             | `boolean`                                                                               | `true`                          | 是否可以调整列宽度                                                                                                                             |
| itemDraggableOn                       | `boolean`                                                                               |                                 | 用[表达式](../../docs/concepts/expression)来配置是否可拖拽排序                                                                                 |
| [saveOrderApi](#saveOrderApi)         | [API](../../docs/types/api)                                                             |                                 | 保存排序的 api。                                                                                                                               |
| [quickSaveApi](#quickSaveApi)         | [API](../../docs/types/api)                                                             |                                 | 快速编辑后用来批量保存的 API。                                                                                                                 |
| [quickSaveItemApi](#quickSaveItemApi) | [API](../../docs/types/api)                                                             |                                 | 快速编辑配置成及时保存时使用的 API。                                                                                                           |
| bulkActions                           | Array<[Action](./action)>                                                               |                                 | 批量操作列表，配置后，表格可进行选中操作。                                                                                                     |
| messages                              | `Object`                                                                                |                                 | 覆盖消息提示，如果不指定，将采用 api 返回的 message                                                                                            |
| messages.fetchFailed                  | `string`                                                                                |                                 | 获取失败时提示                                                                                                                                 |
| messages.saveOrderFailed              | `string`                                                                                |                                 | 保存顺序失败提示                                                                                                                               |
| messages.saveOrderSuccess             | `string`                                                                                |                                 | 保存顺序成功提示                                                                                                                               |
| messages.quickSaveFailed              | `string`                                                                                |                                 | 快速保存失败提示                                                                                                                               |
| messages.quickSaveSuccess             | `string`                                                                                |                                 | 快速保存成功提示                                                                                                                               |
| primaryField                          | `string`                                                                                | `"id"`                          | 设置 ID 字段名。                                                                                                                               |
| perPage                               | `number`                                                                                | 10                              | 设置一页显示多少条数据。                                                                                                                       |
| orderBy                               | `string`                                                                                |                                 | 默认排序字段，这个是传给后端，需要后端接口实现                                                                                                 |
| orderDir                              | `asc` \| `desc`                                                                         |                                 | 排序方向                                                                                                                                       |
| defaultParams                         | `Object`                                                                                |                                 | 设置默认 filter 默认参数，会在查询的时候一起发给后端                                                                                           |
| pageField                             | `string`                                                                                | `"page"`                        | 设置分页页码字段名。                                                                                                                           |
| perPageField                          | `string`                                                                                | `"perPage"`                     | 设置分页一页显示的多少条数据的字段名。注意：最好与 defaultParams 一起使用，请看下面例子。                                                      |
| totalField                            | `string`                                                                                | `"total"`                       | 设置数据返回中用来表示数据总量的字段名                                                                                                         |
| pageDirectionField                    | `string`                                                                                | `"pageDir"`                     | 分页方向字段名可能是 forward 或者 backward                                                                                                     |
| perPageAvailable                      | `Array<number>`                                                                         | `[5, 10, 20, 50, 100]`          | 设置一页显示多少条数据下拉框可选条数。                                                                                                         |
| orderField                            | `string`                                                                                |                                 | 设置用来确定位置的字段名，设置后新的顺序将被赋值到该字段中。                                                                                   |
| hideQuickSaveBtn                      | `boolean`                                                                               | `false`                         | 隐藏顶部快速保存提示                                                                                                                           |
| autoJumpToTopOnPagerChange            | `boolean`                                                                               | `false`                         | 当切分页的时候，是否自动跳顶部。                                                                                                               |
| syncResponse2Query                    | `boolean`                                                                               | `true`                          | 将返回数据同步到过滤器上。                                                                                                                     |
| keepItemSelectionOnPageChange         | `boolean`                                                                               | `true`                          | 保留条目选择，默认分页、搜索后，用户选择条目会被清空，开启此选项后会保留用户选择，可以实现跨页面批量操作。                                     |
| labelTpl                              | `string`                                                                                |                                 | 单条描述模板，`keepItemSelectionOnPageChange`设置为`true`后会把所有已选择条目列出来，此选项可以用来定制条目展示文案。                          |
| maxKeepItemSelectionLength            | `number`                                                                                | `true`                          | 和`keepItemSelectionOnPageChange`搭配使用，限制最大勾选数。                                                                                    |
| maxItemSelectionLength                | `number`                                                                                | `true`                          | 可单独使用限制当前页的最大勾选数，也可以和`keepItemSelectionOnPageChange`搭配使用达到和 maxKeepItemSelectionLength 一样的效果。                |
| headerToolbar                         | Array                                                                                   | `['bulkActions', 'pagination']` | 顶部工具栏配置                                                                                                                                 |
| footerToolbar                         | Array                                                                                   | `['statistics', 'pagination']`  | 底部工具栏配置                                                                                                                                 |
| alwaysShowPagination                  | `boolean`                                                                               | `false`                         | 是否总是显示分页                                                                                                                               |
| affixHeader                           | `boolean`                                                                               | `true`                          | 是否固定表头(table 下)                                                                                                                         |
| affixFooter                           | `boolean`                                                                               | `false`                         | 是否固定表格底部工具栏                                                                                                                         |
| autoGenerateFilter                    | `Object \| boolean`                                                                     |                                 | 是否开启查询区域，开启后会根据列元素的 `searchable` 属性值，自动生成查询条件表单                                                               |
| resetPageAfterAjaxItemAction          | `boolean`                                                                               | `false`                         | 单条数据 ajax 操作后是否重置页码为第一页                                                                                                       |
| autoFillHeight                        | `boolean` 丨 `{height: number}`                                                         |                                 | 内容区域自适应高度                                                                                                                             |
| canAccessSuperData                    | `boolean`                                                                               | `true`                          | 指定是否可以自动获取上层的数据并映射到表格行数据上，如果列也配置了该属性，则列的优先级更高                                                     |
| matchFunc                             | `string`                                                                                | [`CRUDMatchFunc`](#匹配函数)    | 自定义匹配函数, 当开启`loadDataOnce`时，会基于该函数计算的匹配结果进行过滤，主要用于处理列字段类型较为复杂或者字段值格式和后端返回不一致的场景 | `3.5.0` |
| parsePrimitiveQuery                   | [`ParsePrimitiveQueryOptions`](#ParsePrimitiveQueryOptions)                             | `true`                          | 是否开启 Query 信息转换，开启后将会对 url 中的 Query 进行转换，默认开启，默认仅转化布尔值                                                      | `3.6.0` |

注意除了上面这些属性，CRUD 在不同模式下的属性需要参考各自的文档，比如

- 默认[Table](./table)模式里的[列配置](./table#列配置属表)。
- [Cards](./cards) 模式。
- [List](./list) 模式。

### 列配置属性表

除了 Table 组件默认支持的列配置，CRUD 的列配置还额外支持以下属性：

| 属性名             | 类型                                                         | 默认值    | 说明                                                                                                           | 版本    |
| ------------------ | ------------------------------------------------------------ | --------- | -------------------------------------------------------------------------------------------------------------- | ------- |
| sortable           | `boolean`                                                    | `false`   | 是否可排序                                                                                                     |
| searchable         | `boolean` \| `Schema`                                        | `false`   | 是否可快速搜索，开启`autoGenerateFilter`后，`searchable`支持配置`Schema`                                       |
| filterable         | `boolean` \| [`QuickFilterConfig`](./crud#quickfilterconfig) | `false`   | 是否可快速搜索，`options`属性为静态选项，支持设置`source`属性从接口获取选项                                    |
| quickEdit          | `boolean` \| [`QuickEditConfig`](./crud#quickeditconfig)     | -         | 快速编辑，一般需要配合`quickSaveApi`接口使用                                                                   |
| quickEditEnabledOn | `SchemaExpression`                                           | -         | 开启快速编辑条件[表达式](../../docs/concepts/expression)                                                       |         |
| textOverflow       | `string`                                                     | `default` | 文本溢出后展示形式，默认换行处理。可选值 `ellipsis` 溢出隐藏展示， `noWrap` 不换行展示(仅在列为静态文本时生效) | `6.9.0` |

#### QuickFilterConfig

| 属性名        | 类型                                      | 默认值  | 说明                                                     | 版本                        |
| ------------- | ----------------------------------------- | ------- | -------------------------------------------------------- | --------------------------- |
| options       | `Array<any>`                              | -       | 静态选项                                                 |                             |
| multiple      | `boolean`                                 | `false` | 是否支持多选                                             |                             |
| source        | [`Api`](../../docs/types/api) \| `string` | -       | 选项 API 接口                                            | `3.6.0`版本后支持上下文变量 |
| refreshOnOpen | `boolean`                                 | `false` | 配置 source 前提下，每次展开筛选浮层是否重新加载选项数据 | `2.9.0`                     |
| strictMode    | `boolean`                                 | `false` | 严格模式，开启严格模式后，会采用 JavaScript 严格相等比较 | `2.3.0`                     |

#### QuickEditConfig

| 属性名          | 类型                      | 默认值      | 说明                                                                                                    | 版本    |
| --------------- | ------------------------- | ----------- | ------------------------------------------------------------------------------------------------------- | ------- |
| type            | `SchemaType`              | -           | 表单项组件类型                                                                                          |         |
| body            | `SchemaCollection`        | -           | 组件容器，支持多个表单项组件                                                                            |         |
| mode            | `'inline' \| 'popOver'`   | `'popOver'` | 编辑模式，inline 为行内编辑，popOver 为浮层编辑                                                         |         |
| icon            | `string`                  | -           | 自定义快速编辑按钮的图标                                                                                | `6.1.0` |
| saveImmediately | `boolean` 或 `{api: Api}` | `false`     | 是否修改后即时保存，一般需要配合`quickSaveItemApi`接口使用，也可以直接配置[`Api`](../../docs/types/api) |         |
| resetOnFailed   | `boolean`                 | -           | 接口请求失败时，是否重置数据                                                                            |         |

### columns-toggler 属性表

| 属性名           | 类型                           | 默认值    | 说明                                   |
| ---------------- | ------------------------------ | --------- | -------------------------------------- |
| label            | `string`                       |           | 按钮文字                               |
| tooltip          | `string`                       |           | 按钮提示文字                           |
| disabledTip      | `string`                       |           | 按钮禁用状态下的提示                   |
| align            | `"left" \| "right"`            | `"left"`  | 点击内容是否关闭                       |
| size             | `"xs" \| "sm" \| "md" \| "lg"` |           | 按钮大小，参考[按钮](./action)         |
| footerBtnSize    | `"xs" \| "sm" \| "md" \| "lg"` |           | 弹窗底部按钮大小，参考[按钮](./action) |
| level            | `string`                       | `default` | 按钮样式，参考[按钮](./action)         |
| draggable        | `boolean`                      | `false`   | 是否可通过拖拽排序                     |
| defaultIsOpened  | `boolean`                      | `false`   | 默认是否展开                           |
| hideExpandIcon   | `boolean`                      | `true`    | 是否隐藏展开的图标                     |
| overlay          | `boolean`                      | `false`   | 是否显示遮罩层                         |
| closeOnOutside   | `boolean`                      |           | 点击外部是否关闭                       |
| closeOnClick     | `boolean`                      |           | 点击内容是否关闭                       |
| iconOnly         | `boolean`                      | `false`   | 是否只显示图标。                       |
| icon             | `string`                       |           | 按钮的图标                             |
| className        | `string`                       |           | 外层 CSS 类名                          |
| btnClassName     | `string`                       |           | 按钮的 CSS 类名                        |
| modalSize        | `string`                       |           | 弹窗大小，参考[弹窗](./dialog)         |
| modalWidth       | `string`                       |           | 弹窗宽度                               |
| modalHeight      | `string`                       |           | 弹窗高度                               |
| modalColumnCount | `number`                       |           | 弹窗内每行显示的列数                   |

## 事件表

当前组件会对外派发以下事件，可以通过`onEvent`来监听这些事件，并通过`actions`来配置执行的动作，在`actions`中可以通过`${事件参数名}`或`${event.data.[事件参数名]}`来获取事件产生的数据，详细查看[事件动作](../../docs/concepts/event-action)。

| 事件名称          | 事件参数                                                                                                                                                                                                                                                                    | 说明                                                           |
| ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------- |
| fetchInited       | `responseData` 接口数据返回 <br /> `responseStatus` 接口返回状态 <br /> `responseMsg` 响应消息                                                                                                                                                                              | 远程初始化数据接口请求完成时触发                               |
| quickSaveSucc     | `result` 接口数据返回 <br /> `rows: object[]` 修改了的行集合 <br /> `rowsDiff: object[]` 与 rows 不同的地方时，对象中只有修改的部分和主键字段 <br /> `indexes: Array<string>` 修改的行索引，如果是树形模式，下标是字符串路劲如 `0.1` <br /> `rowsOrigin: object[]` 原始数据 | 快速编辑完后保存成功触发                                       |
| quickSaveFail     | `error` 错误原因                                                                                                                                                                                                                                                            | 快速编辑完后保存失败                                           |
| quickSaveItemSucc | `result` 接口数据返回 <br /> `item: object` 当亲修改的那行数据 <br /> `modified:object` 质只包含修改的部分 <br /> `origin: object` 原始数据                                                                                                                                 | 快速编辑单条保存成功后触发                                     |
| quickSaveItemFail | `error` 错误原因                                                                                                                                                                                                                                                            | 快速编辑单条保存失败后触发                                     |
| saveOrderSucc     | `result` 接口数据返回 <br /> `其他` 请参考 [拖拽排序](#拖拽排序) 章节说明                                                                                                                                                                                                   | 拖拽排序保存成功后触发                                         |
| saveOrderFail     | `error` 错误原因                                                                                                                                                                                                                                                            | 拖拽排序保存失败后触发                                         |
| selectedChange    | `selectedItems: item[]` 已选择行<br/>`selectedIndexes: string[]` 已选择行索引 <br/>`unSelectedItems: item[]` 未选择行                                                                                                                                                       | 手动选择表格项时触发                                           |
| columnSort        | `orderBy: string` 列排序列名<br/>`orderDir: string` 列排序值                                                                                                                                                                                                                | 点击列排序时触发                                               |
| columnFilter      | `filterName: string` 列筛选列名<br/>`filterValue: string \| undefined` 列筛选值                                                                                                                                                                                             | 点击列筛选时触发，点击重置后事件参数`filterValue`为`undefined` |
| columnSearch      | `searchName: string` 列搜索列名<br/>`searchValue: object` 列搜索数据                                                                                                                                                                                                        | 点击列搜索时触发                                               |
| orderChange       | `movedItems: item[]` 已排序数据                                                                                                                                                                                                                                             | 手动拖拽行排序时触发                                           |
| columnToggled     | `columns: item[]` 当前显示的列配置数据                                                                                                                                                                                                                                      | 点击自定义列时触发                                             |
| rowClick          | `item: object` 行点击数据<br/>`index: number` 行索引 <br />`indexPath: string` 行索引路径                                                                                                                                                                                   | 点击整行时触发                                                 |
| rowDbClick        | `item: object` 行点击数据<br/>`index: number` 行索引 <br />`indexPath: string` 行索引路径                                                                                                                                                                                   | 双击整行时触发                                                 |
| rowMouseEnter     | `item: object` 行移入数据<br/>`index: number` 行索引 <br />`indexPath: string` 行索引路径                                                                                                                                                                                   | 移入整行时触发                                                 |
| rowMouseLeave     | `item: object` 行移出数据<br/>`index: number` 行索引 <br />`indexPath: string` 行索引路径                                                                                                                                                                                   | 移出整行时触发                                                 |

### selectedChange

在开启批量操作后才会用到，可以尝试勾选列表的行记录。

```schema: scope="body"
{
  "type": "page",
  "body": {
    "type": "crud",
    "api": "/api/mock2/sample",
    "syncLocation": false,
    "onEvent": {
      "selectedChange": {
        "actions": [
          {
            "actionType": "toast",
            "args": {
              "msg": "已选择${event.data.selectedItems.length}条记录"
            }
          }
        ]
      }
    },
    "bulkActions": [
        {
            "label": "批量删除",
            "actionType": "ajax",
            "api": "delete:/api/mock2/sample/${ids|raw}",
            "confirmText": "确定要批量删除?"
        }
    ],
    "columns": [
      {
        "name": "id",
        "label": "ID"
      },
      {
        "name": "engine",
        "label": "Rendering engine"
      },
      {
        "name": "browser",
        "label": "Browser"
      },
      {
        "name": "platform",
        "label": "Platform(s)"
      },
      {
        "name": "version",
        "label": "Engine version"
      },
      {
        "name": "grade",
        "label": "CSS grade"
      }
    ]
  }
}
```

### columnSort

列排序，可以尝试点击`Browser`列右侧的排序图标。

```schema: scope="body"
{
  "type": "page",
  "body": {
    "type": "crud",
    "api": "/api/mock2/sample",
    "syncLocation": false,
    "onEvent": {
      "columnSort": {
            "actions": [
                {
                    "actionType": "toast",
                    "args": {
                    "msgType": "info",
                    "msg": "orderBy：${event.data.orderBy},orderDir：${event.data.orderDir}"
                    }
                }
            ]
        }
    },
    "bulkActions": [
        {
            "label": "批量删除",
            "actionType": "ajax",
            "api": "delete:/api/mock2/sample/${ids|raw}",
            "confirmText": "确定要批量删除?"
        }
    ],
    "columns": [
      {
        "name": "id",
        "label": "ID",
        "searchable": true
      },
      {
        "name": "engine",
        "label": "Rendering engine",
        "filterable": {
            "options": [
                "Internet Explorer 4.0",
                "Internet Explorer 5.0"
            ]
        }
      },
      {
        "name": "browser",
        "label": "Browser",
        "sortable": true
      },
      {
        "name": "platform",
        "label": "Platform(s)"
      },
      {
        "name": "version",
        "label": "Engine version"
      },
      {
        "name": "grade",
        "label": "CSS grade"
      }
    ]
  }
}
```

### columnFilter

列过滤，可以尝试点击`Rendering engine`列右侧的筛选图标。

```schema: scope="body"
{
  "type": "page",
  "body": {
    "type": "crud",
    "api": "/api/mock2/sample",
    "syncLocation": false,
    "onEvent": {
        "columnFilter": {
            "actions": [
                {
                    "actionType": "toast",
                    "args": {
                    "msgType": "info",
                    "msg": "filterName：${event.data.filterName},filterValue：${event.data.filterValue}"
                    }
                }
            ]
        }
    },
    "bulkActions": [
        {
            "label": "批量删除",
            "actionType": "ajax",
            "api": "delete:/api/mock2/sample/${ids|raw}",
            "confirmText": "确定要批量删除?"
        }
    ],
    "columns": [
      {
        "name": "id",
        "label": "ID",
        "searchable": true
      },
      {
        "name": "engine",
        "label": "Rendering engine",
        "filterable": {
            "options": [
                "Internet Explorer 4.0",
                "Internet Explorer 5.0"
            ]
        }
      },
      {
        "name": "browser",
        "label": "Browser",
        "sortable": true
      },
      {
        "name": "platform",
        "label": "Platform(s)"
      },
      {
        "name": "version",
        "label": "Engine version"
      },
      {
        "name": "grade",
        "label": "CSS grade"
      }
    ]
  }
}
```

### columnSearch

列检索，，可以尝试点击`ID`列右侧的检索图标。

```schema: scope="body"
{
  "type": "page",
  "body": {
    "type": "crud",
    "api": "/api/mock2/sample",
    "syncLocation": false,
    "onEvent": {
        "columnSearch": {
            "actions": [
                {
                    "actionType": "toast",
                    "args": {
                    "msgType": "info",
                    "msg": "searchName：${event.data.searchName},searchValue：${event.data.searchValue|json}"
                    }
                }
            ]
        }
    },
    "bulkActions": [
        {
            "label": "批量删除",
            "actionType": "ajax",
            "api": "delete:/api/mock2/sample/${ids|raw}",
            "confirmText": "确定要批量删除?"
        }
    ],
    "columns": [
      {
        "name": "id",
        "label": "ID",
        "searchable": true
      },
      {
        "name": "engine",
        "label": "Rendering engine",
        "filterable": {
            "options": [
                "Internet Explorer 4.0",
                "Internet Explorer 5.0"
            ]
        }
      },
      {
        "name": "browser",
        "label": "Browser",
        "sortable": true
      },
      {
        "name": "platform",
        "label": "Platform(s)"
      },
      {
        "name": "version",
        "label": "Engine version"
      },
      {
        "name": "grade",
        "label": "CSS grade"
      }
    ]
  }
}
```

### columnToggled

点击自定义列，可以尝试修改`自定义列`的配置。

```schema: scope="body"
{
  "type": "page",
  "body": {
    "type": "crud",
    "api": "/api/mock2/sample",
    "syncLocation": false,
    "onEvent": {
      "columnToggled": {
            "actions": [
            {
                "actionType": "toast",
                "args": {
                "msgType": "info",
                "msg": "当前显示${event.data.columns.length}列"
                }
            }
            ]
        }
    },
    "bulkActions": [
        {
            "label": "批量删除",
            "actionType": "ajax",
            "api": "delete:/api/mock2/sample/${ids|raw}",
            "confirmText": "确定要批量删除?"
        }
    ],
    "columns": [
      {
        "name": "id",
        "label": "ID",
        "searchable": true
      },
      {
        "name": "engine",
        "label": "Rendering engine",
        "filterable": {
            "options": [
                "Internet Explorer 4.0",
                "Internet Explorer 5.0"
            ]
        }
      },
      {
        "name": "browser",
        "label": "Browser",
        "sortable": true
      },
      {
        "name": "platform",
        "label": "Platform(s)"
      },
      {
        "name": "version",
        "label": "Engine version"
      },
      {
        "name": "grade",
        "label": "CSS grade"
      }
    ]
  }
}
```

### orderChange

在开启拖拽排序行记录后才会用到，排序确认后触发。

```schema: scope="body"
{
  "type": "page",
  "body": {
    "type": "crud",
    "api": "/api/mock2/sample",
    "syncLocation": false,
    "draggable": true,
    "onEvent": {
      "orderChange": {
            "actions": [
                {
                    "actionType": "toast",
                    "args": {
                        "msgType": "info",
                        "msg": "${event.data.movedItems.length}行发生移动"
                    }
                }
            ]
        }
    },
    "bulkActions": [
        {
            "label": "批量删除",
            "actionType": "ajax",
            "api": "delete:/api/mock2/sample/${ids|raw}",
            "confirmText": "确定要批量删除?"
        }
    ],
    "columns": [
      {
        "name": "id",
        "label": "ID",
        "searchable": true
      },
      {
        "name": "engine",
        "label": "Rendering engine",
        "filterable": {
            "options": [
                "Internet Explorer 4.0",
                "Internet Explorer 5.0"
            ]
        }
      },
      {
        "name": "browser",
        "label": "Browser",
        "sortable": true
      },
      {
        "name": "platform",
        "label": "Platform(s)"
      },
      {
        "name": "version",
        "label": "Engine version"
      },
      {
        "name": "grade",
        "label": "CSS grade"
      }
    ]
  }
}
```

### rowClick

点击行记录。

```schema: scope="body"
{
  "type": "page",
  "body": {
    "type": "crud",
    "api": "/api/mock2/sample",
    "syncLocation": false,
    "onEvent": {
      "rowClick": {
            "actions": [
                {
                    "actionType": "toast",
                    "args": {
                        "msgType": "info",
                        "msg": "行单击数据：${event.data.item|json}；行索引：${event.data.index}"
                    }
                }
            ]
        }
    },
    "bulkActions": [
        {
            "label": "批量删除",
            "actionType": "ajax",
            "api": "delete:/api/mock2/sample/${ids|raw}",
            "confirmText": "确定要批量删除?"
        }
    ],
    "columns": [
      {
        "name": "id",
        "label": "ID",
        "searchable": true
      },
      {
        "name": "engine",
        "label": "Rendering engine",
        "filterable": {
            "options": [
                "Internet Explorer 4.0",
                "Internet Explorer 5.0"
            ]
        }
      },
      {
        "name": "browser",
        "label": "Browser",
        "sortable": true
      },
      {
        "name": "platform",
        "label": "Platform(s)"
      },
      {
        "name": "version",
        "label": "Engine version"
      },
      {
        "name": "grade",
        "label": "CSS grade"
      }
    ]
  }
}
```

### rowDbClick

双击行记录。

```schema: scope="body"
{
  "type": "page",
  "body": {
    "type": "crud",
    "api": "/api/mock2/sample",
    "syncLocation": false,
    "onEvent": {
      "rowDbClick": {
            "actions": [
                {
                    "actionType": "toast",
                    "args": {
                        "msgType": "info",
                        "msg": "行单击数据：${event.data.item|json}；行索引：${event.data.index}"
                    }
                }
            ]
        }
    },
    "columns": [
      {
        "name": "id",
        "label": "ID",
        "searchable": true
      },
      {
        "name": "engine",
        "label": "Rendering engine",
        "filterable": {
            "options": [
                "Internet Explorer 4.0",
                "Internet Explorer 5.0"
            ]
        }
      },
      {
        "name": "browser",
        "label": "Browser",
        "sortable": true
      },
      {
        "name": "platform",
        "label": "Platform(s)"
      },
      {
        "name": "version",
        "label": "Engine version"
      },
      {
        "name": "grade",
        "label": "CSS grade"
      }
    ]
  }
}
```

### rowMouseEnter

鼠标移入行记录。

```schema: scope="body"
{
  "type": "page",
  "body": {
    "type": "crud",
    "api": "/api/mock2/sample",
    "syncLocation": false,
    "onEvent": {
      "rowMouseEnter": {
            "actions": [
                {
                    "actionType": "toast",
                    "args": {
                        "msgType": "info",
                        "msg": "行索引：${event.data.index}"
                    }
                }
            ]
        }
    },
    "bulkActions": [
        {
            "label": "批量删除",
            "actionType": "ajax",
            "api": "delete:/api/mock2/sample/${ids|raw}",
            "confirmText": "确定要批量删除?"
        }
    ],
    "columns": [
      {
        "name": "id",
        "label": "ID",
        "searchable": true
      },
      {
        "name": "engine",
        "label": "Rendering engine",
        "filterable": {
            "options": [
                "Internet Explorer 4.0",
                "Internet Explorer 5.0"
            ]
        }
      },
      {
        "name": "browser",
        "label": "Browser",
        "sortable": true
      },
      {
        "name": "platform",
        "label": "Platform(s)"
      },
      {
        "name": "version",
        "label": "Engine version"
      },
      {
        "name": "grade",
        "label": "CSS grade"
      }
    ]
  }
}
```

### rowMouseLeave

鼠标移出行记录。

```schema: scope="body"
{
  "type": "page",
  "body": {
    "type": "crud",
    "api": "/api/mock2/sample",
    "syncLocation": false,
    "onEvent": {
      "rowMouseLeave": {
            "actions": [
                {
                    "actionType": "toast",
                    "args": {
                        "msgType": "info",
                        "msg": "行索引：${event.data.index}"
                    }
                }
            ]
        }
    },
    "bulkActions": [
        {
            "label": "批量删除",
            "actionType": "ajax",
            "api": "delete:/api/mock2/sample/${ids|raw}",
            "confirmText": "确定要批量删除?"
        }
    ],
    "columns": [
      {
        "name": "id",
        "label": "ID",
        "searchable": true
      },
      {
        "name": "engine",
        "label": "Rendering engine",
        "filterable": {
            "options": [
                "Internet Explorer 4.0",
                "Internet Explorer 5.0"
            ]
        }
      },
      {
        "name": "browser",
        "label": "Browser",
        "sortable": true
      },
      {
        "name": "platform",
        "label": "Platform(s)"
      },
      {
        "name": "version",
        "label": "Engine version"
      },
      {
        "name": "grade",
        "label": "CSS grade"
      }
    ]
  }
}
```

### 列的事件表

表格的默认列定义的事件如下，即 click、mouseenter、mouseleave。如果列定义是其他组件，则事件表就是这个组件对应的事件表，例如列定义是 Switch 组件，则可以监听 [Switch 的 change 事件](./form/switch#%E4%BA%8B%E4%BB%B6%E8%A1%A8)。

| 事件名称   | 事件参数                            | 说明                                           |
| ---------- | ----------------------------------- | ---------------------------------------------- |
| click      | `[columnName]: string` 对应列名的值 | 监听表格列点击事件，表格数据点击时触发         |
| mouseenter | `[columnName]: string` 对应列名的值 | 监听表格列鼠标移入事件，表格数据鼠标移入时触发 |
| mouseleave | `[columnName]: string` 对应列名的值 | 监听表格列鼠标移出事件，表格数据鼠标移出时触发 |

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 动作表

当前组件对外暴露以下特性动作，其他组件可以通过指定`actionType: 动作名称`、`componentId: 该组件id`来触发这些动作，动作配置可以通过`args: {动作配置项名称: xxx}`来配置具体的参数，详细请查看[事件动作](../../docs/concepts/event-action#触发其他组件的动作)。

| 动作名称        | 动作配置              | 说明                       |
| --------------- | --------------------- | -------------------------- |
| reload          | -                     | 刷新列表请求               |
| setValue        | `value: object`       | 更新列表记录               |
| select          | 转 table 组件动作说明 | 设置选中项                 |
| selectAll       | 转 table 组件动作说明 | 设置表格全部项选中         |
| clearAll        | 转 table 组件动作说明 | 清空表格所有选中项         |
| initDrag        | 转 table 组件动作说明 | 开启表格拖拽排序功能       |
| cancelDrag      | 转 table 组件动作说明 | 取消表格拖拽排序功能       |
| submitQuickEdit | 转 table 组件动作说明 | 快速编辑数据提交           |
| toggleExpanded  | 转 table 组件动作说明 | 切换某行数据是展开还是收起 |
| setExpanded     | 转 table 组件动作说明 | 展开或收起某行数据         |

value 结构说明：

| 属性名         | 类型     | 默认值 | 说明     |
| -------------- | -------- | ------ | -------- |
| items 或 rows  | `item[]` |        | 列表记录 |
| count 或 total | `number` |        | 记录总数 |

### 初始选中行

利用 `fetchInited` 事件和 `select` 动作可以完成初始选中行。

```
/* Detailed source-code truncated for AI context efficiency. */
```

### reload

#### 只做刷新

重新发送`api`请求，刷新 CRUD 时，只配置`componentId`目标组件 ID 即可。

```
/* Detailed source-code truncated for AI context efficiency. */
```

#### 追加请求参数并刷新

刷新 CRUD 时，如果配置了`data`，将先发送`data`给目标 CRUD 组件，并将该数据合并到目标 CRUD 组件的数据域中，然后重启请求数据，并且自动追加`data`参数到请求中。

```
/* Detailed source-code truncated for AI context efficiency. */
```

通过`&: $$`追加触发事件的按钮所在数据域的所有数据，即`name、age、date`。

```
/* Detailed source-code truncated for AI context efficiency. */
```

#### 局部刷新（仅刷新指定行）

> `6.3.0`及以上版本

需要搭配 `deferApi` 属性使用，同时刷新动作指定 `args.index` 或者 `args.condition` 来指定刷新哪一行。

```schema
{
  "type": "page",
  "data": {
    "name": "amis",
    "age": 18,
    "date": "2023-6-6"
  },
  "body": [
    {
      "type": "button",
      "label": "刷新 id 为 2 的行",
      level: 'primary',
      "className": "mb-2",
      "onEvent": {
        "click": {
          "actions": [
            {
              "componentId": "crud_reload1",
              "actionType": "reload",
              "args": {
                "condition": "${id == 2}"
              }
            },

            {
              "componentId": "crud_reload1",
              "actionType": "setExpanded",
              "args": {
                "condition": "${id == 2}",
                "value": true
              }
            }
          ]
        }
      }
    },
    {
      "type": "crud",
      "api": "/api/mock2/crud/table6",
      "deferApi": "/api/mock2/crud/table6?parentId=${id}&waitSeconds=2",
      "id": "crud_reload1",
      "syncLocation": false,
      "columns": [
        {
          "name": "id",
          "label": "ID"
        },
        {
          "name": "engine",
          "label": "Rendering engine"
        },
        {
          "name": "browser",
          "label": "Browser"
        },
        {
          "name": "platform",
          "label": "Platform(s)"
        },
        {
          "name": "version",
          "label": "Engine version"
        },
        {
          "name": "grade",
          "label": "CSS grade"
        }
      ]
    }
  ]
}
```

### toggleExpanded

> `6.3.0`及以上版本

切换展开状态。通过指定 `args.index` 或者 `args.condition` 来指定切换哪一行。

参考局部刷新里面的示例。

### setExpanded

> `6.3.0`及以上版本

设置展开状态。通过指定 `args.index` 或者 `args.condition` 来指定切换哪一行，通过 `args.value` 来设置是展开还是收起。

参考局部刷新里面的示例。

### setValue

通过`setValue`更新指定 CRUD 的数据。

#### 合并数据

默认`setValue`会将新数据与目标组件数据进行合并。

```schema: scope="body"
[
    {
      "type": "button",
      "label": "更新数据，记录总数被更新为20",
      "onEvent": {
        "click": {
          "actions": [
            {
              "actionType": "setValue",
              "componentId": "crud_setvalue",
              "args": {
                "value": {
                  "count": 20
                }
              }
            }
          ]
        }
      }
    },
    {
      "type": "crud",
      "id": "crud_setvalue",
      "syncLocation": false,
      "api": "/api/mock2/sample",
      "quickSaveApi": "/api/mock2/sample/bulkUpdate",
      "headerToolbar": [
        {
          "type": "tpl",
          "tpl": "记录总数：${count}"
        }
      ],
      "columns": [
        {
          "name": "id",
          "label": "ID",
          "id": "u:3db3f2b1b99e"
        },
        {
          "name": "engine",
          "label": "engine",
          "id": "u:0b9be99f3403"
        },
        {
          "name": "version",
          "label": "version",
          "id": "u:4868d7db0139"
        }
      ]
    }
]
```

#### 覆盖数据

可以通过`"dataMergeMode": "override"`来覆盖目标组件数据。

```
/* Detailed source-code truncated for AI context efficiency. */
```

#### 更新列表记录

```
/* Detailed source-code truncated for AI context efficiency. */
```

#### 更新指定行记录

可以通过指定`index`或者`condition`来分别更新指定索引的行记录和指定满足条件（条件表达式或者 ConditionBuilder）的行记录，另外`replace`同样生效，即可以完全替换指定行记录，也可以对指定行记录做合并。

```
/* Detailed source-code truncated for AI context efficiency. */
```

#### 提交数据更改

通过表达式或者行号更新数据后，并不会提交到后端，需要添加 `submitQuickEdit` 动作来提交。

```
/* Detailed source-code truncated for AI context efficiency. */
```

#### 行记录中字段赋值

需要通过表达式配置动态`id`和`componentId`。例如修改`engine`选中状态的同时选中`version`，勾选`id`的同时去掉对`engine`的选中。

```
/* Detailed source-code truncated for AI context efficiency. */
```

---

### Zh CN Components Custom (`docs/zh-CN/components/custom.md`)

---
title: Custom 自定义组件
description:
type: 0
group: ⚙ 组件
menuName: Custom 自定义组件
icon:
order: 26
---

用于实现自定义组件，它解决了之前 JS SDK 和可视化编辑器中难以支持自定义组件的问题。

## 基本用法

设置 type 类型为 custom

### onMount

这是节点在初始化的时候执行的函数，它接收三个参数：

- dom，组件加载之后的 dom 节点
- data，组件初始值，需要设置 name
- onChange，修改这个组件对应 name 的值
- props，后面会单独介绍

比如在这样的 form 组件中：

```javascript
{
  type: 'page',
  title: '表单页面',
  body: {
    type: 'form',
    title: 'custom 组件',
    body: [
      {
        type: 'custom',
        name: 'myName',
        label: '自定义组件',
        onMount: (dom, value, onChange, props) => {
          const button = document.createElement('button');
          button.innerText = '点击修改';
          button.onclick = event => {
            // 这个 onChange 方法只有放在表单项中才能调用，第二个参数是表单项名称
            onChange('new', 'myName');
            event.preventDefault();
          };
          dom.appendChild(button);
        }
      }
    ]
  }
}
```

点击按钮之后，执行 `onChange` 函数，就会将 `myName` 这个参数的值改成 `new`，点击表单提交的时候，就会有一个 `myName=new` 的表单数据。

### onUpdate

onUpdate 是在数据变更的时候调用，注意这个数据变更会包含表单内的所有其他组件。

```javascript
{
  type: 'page',
  title: '表单页面',
  body: {
    type: 'form',
    title: 'custom 组件',
    body: [
      {
        name: 'email',
        label: '邮箱',
        type: 'input-text'
      },
      {
        name: 'username',
        label: '用户名',
        type: 'input-text'
      },
      {
        type: 'custom',
        label: '自定义组件',
        onUpdate: (dom, data, prevData, props) => {
          console.log('data', data, prevData)
        }
      }
    ]
  }
}
```

这个例子中，无论是邮箱还是用户名修改，都会触发 onUpdata 函数，其中 `data` 是当前值，`prevData` 是之前的值：

1. 如果修改 email，则 data 将会是 `{email: 'xxx'}`，prevData 是 `{}`
2. 如果再次修改 email，则 data 将会是 `{email: 'xxx1'}`，prevData 是 `{email: 'xxx '}`
3. 如果修改 username，则 data 将会是 `{email: 'xxx1', username: 'yyy'}`，prevData 是 `{email: 'xxx1'}`

### onUnmount

onUnmount 是在组件销毁的时候执行，可以在这里做资源清理，这个函数只有一个 props 参数。

### Vue.js

因为 onMount 拿到的 dom 就是标准的 dom，所以可以执行任意 JavaScript 代码，包括 jQuery 等，下面的例子演示了如何使用 vue 2.0 实现自定义组件：

```javascript
{
  type: 'page',
  title: '表单页面',
  body: {
    type: 'form',
    title: 'custom 组件',
    body: [
      {
        type: 'custom',
        name: 'my-custom',
        html: `
        <ol>
          <li v-for="todo in todos">
            {{ todo.text }}
          </li>
        </ol>
        `,
        label: '自定义组件',
        onMount: (dom, data, onChange, props) => {
          const app = new Vue({
            el: dom,
            data: {
              todos: [
                { text: 'hello' },
                { text: 'world' },
                { text: 'vue' }
              ]
            }
          })
        }
      }
    ]
  }
}
```
【温馨提示】   
custom 组件中使用 vue2 语法，请先引入vue.js（umd 或 global 模块，比如：https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js） 。   
同理，使用 vue3 语法请先引入 vue3 对应的 umd 或 global 模块，比如：https://unpkg.com/vue@3/dist/vue.global.js 。

### props

前面可以看到所有函数最后都有一个 props 参数，在这个参数里能拿到 amis 内部属性和方法，比如弹框

```javascript
onMount: (dom, data, onChange, props) => {
  const button = document.createElement('button');
  button.innerText = '点击修改姓名';
  button.onclick = event => {
    onChange('new name', 'name');
    props.onAction(
      event,
      {
        type: 'action',
        label: '弹个框',
        actionType: 'dialog',
        dialog: {
          title: '弹框',
          body: 'Hello World!'
        }
      },
      {} // 这是 data
    );
    event.preventDefault();
  };
  dom.appendChild(button);
};
```

或者执行 `props.env.notify('success', '执行成功')` 来在右上角弹出提示等。

## 属性表

| 属性名    | 类型      | 默认值   | 说明                                          |
| --------- | --------- | -------- | --------------------------------------------- |
| type      | 'custom'  |          |                                               |
| id        | `string`  |          | 节点 id                                       |
| name      | `string`  |          | 节点 名称                                     |
| className | `string`  |          | 节点 class                                    |
| inline    | `boolean` | false    | 默认使用 div 标签，如果 true 就使用 span 标签 |
| html      | `string`  |          | 初始化节点 html                               |
| onMount   | `string`  | Function | 节点初始化之后调的用函数                      |
| onUpdate  | `string`  | Function | 数据有更新的时候调用的函数                    |
| onUnmount | `string`  | Function | 节点销毁的时候调用的函数                      |

---

### Zh CN Components Date (`docs/zh-CN/components/date.md`)

---
title: Date 日期时间
description:
type: 0
group: ⚙ 组件
menuName: Date
icon:
order: 39
---

用于展示日期

## 基本使用

```schema
{
    "type": "page",
    "body": {
        "type": "date",
        "value": "1591326307"
    }
}
```

## 用作 Field 时

当用在 Table 的列配置 Column、List 的内容、Card 卡片的内容和表单的 Static-XXX 中时，可以设置`name`属性，映射同名变量

### Table 中的列类型

```schema: scope="body"
{
    "type": "table",
    "data": {
        "items": [
            {
                "id": "1",
                "date": "1591326307"
            },
            {
                "id": "2",
                "date": "1591321307"
            },
            {
                "id": "3",
                "date": "1591322307"
            }
        ]
    },
    "columns": [
        {
            "name": "id",
            "label": "Id"
        },

        {
            "name": "date",
            "label": "日期",
            "type": "date"
        }
    ]
}
```

List 的内容、Card 卡片的内容配置同上

### Form 中静态展示

```schema: scope="body"
{
    "type": "form",
    "data": {
        "now": "1591322307"
    },
    "body": [
        {
            "type": "static-date",
            "name": "now",
            "label": "日期",
            "format": "YYYY年MM月DD日 HH时mm分ss秒"
        }
    ]
}
```

## 配置展示格式

例如你想将某一个时间值，以 `xxxx年xx月xx日 xx时xx分xx秒` 这样的格式输出，那么查找 [moment 文档](https://momentjs.com/docs/#/displaying/format/) 可知配置格式应为 `YYYY年MM月DD日 HH时mm分ss秒`，即：

```schema
{
  "type": "page",
  "data": {
    "now": 1586865590
  },
  "body": {
    "type": "date",
    "value": "1586865590",
    "format": "YYYY年MM月DD日 HH时mm分ss秒"
  }
}
```

## 配置数据格式

如果你的数据值默认不是`X`格式（时间戳秒格式），那么需要配置 `valueFormat` 参数用于解析当前时间值，比如毫秒是配置 `"valueFormat": "x"`。

除此之外还支持各种自定义日期格式，例如下面`value`值为：`"2020/4/14 19:59:50"`，查阅 [moment 文档](https://momentjs.com/docs/#/displaying/format/) 可知，需要配置数据格式为 `"YYYY/MM/DD HH:mm:ss"`，然后我们配置输出格式`format`，输出指定格式日期：

```schema
{
  "type": "page",
  "body": {
    "type": "date",
    "value": "2020/4/14 19:59:50",
    "valueFormat": "YYYY/MM/DD HH:mm:ss",
    "format": "YYYY年MM月DD日 HH时mm分ss秒"
  }
}
```

## 转成相对当前时间的描述

```schema
{
    "type": "page",
    "body": {
        "type": "date",
        "fromNow": true,
        "value": "1591326307"
    }
}
```

## 设置展示时区

通过配置 `displayTimeZone` 参数，可以设置展示时区，默认展示当前时区。

```schema: scope="body"
{
    "type": "crud",
    "api": {
      "method": "get",
      "url": "/whatever/api",
      "mockResponse": {
        "status": 200,
        "data": [
          {
            "date": "2023-10-27 15:00:00"
          }
        ]
      }
    },
    "columns": [
      {
        "type": "date",
        "label": "Asia/Shanghai",
        "name": "date",
        "displayTimeZone": "Asia/Shanghai",
        "format": "YYYY-MM-DD HH:mm:ss"
      },
      {
        "type": "date",
        "label": "America/Los_Angeles",
        "name": "date",
        "displayTimeZone": "America/Los_Angeles",
        "format": "YYYY-MM-DD HH:mm:ss"
      },
      {
        "type": "date",
        "name": "date",
        "label": "Asia/Tokyo",
        "displayTimeZone": "Asia/Tokyo",
        "format": "YYYY-MM-DD HH:mm:ss"
      }
    ]
  }
```

## 属性表

| 属性名          | 类型      | 默认值       | 说明                                                                                                   | 版本                    |
| --------------- | --------- | ------------ | ------------------------------------------------------------------------------------------------------ | ----------------------- |
| type            | `string`  |              | 如果在 Table、Card 和 List 中，为`"date"`；在 Form 中用作静态展示，为`"static-date"`                   |
| className       | `string`  |              | 外层 CSS 类名                                                                                          |
| value           | `string`  |              | 显示的日期数值                                                                                         |
| name            | `string`  |              | 在其他组件中，时，用作变量映射                                                                         |
| placeholder     | `string`  | `-`          | 占位内容                                                                                               |
| displayFormat   | `string`  | `YYYY-MM-DD` | 展示格式, 更多格式类型请参考 [文档](https://momentjs.com/docs/#/displaying/format/)                    | 版本号 3.4.0 及以上支持 |
| valueFormat     | `string`  | `X`          | 数据格式，默认为时间戳。更多格式类型请参考 [文档](https://momentjs.com/docs/#/displaying/format/)      |
| fromNow         | `boolean` | `false`      | 是否显示相对当前的时间描述，比如: 11 小时前、3 天前、1 年前等，fromNow 为 true 时，format 不生效。     |
| updateFrequency | `number`  | `60000`      | 更新频率， 默认为 1 分钟                                                                               |
| displayTimeZone | `string`  |              | 设置日期展示时区，可设置清单参考：https://gist.github.com/diogocapela/12c6617fc87607d11fd62d2a4f42b02a |

---

### Zh CN Components Dialog (`docs/zh-CN/components/dialog.md`)

---
title: Dialog 对话框
description:
type: 0
group: ⚙ 组件
menuName: Dialog 对话框
icon:
order: 41
---

Dialog 弹框 主要由 [Action](./action) 触发，主要展示一个对话框以供用户操作。

## 基本用法

```schema: scope="body"
{
    "label": "点击弹框",
    "type": "button",
    "actionType": "dialog",
    "dialog": {
      "title": "弹框标题",
      "body": "这是一个弹框"
    }
}
```

## 配置尺寸

```schema: scope="body"
{
    "type": "button-toolbar",
    "buttons": [
        {
            "type": "button",
            "label": "较小的弹框",
            "actionType": "dialog",
            "dialog": {
                "size": "sm",
                "title": "提示",
                "body": "这是个简单的弹框"
            }
        },
        {
            "type": "button",
            "label": "标准弹框",
            "actionType": "dialog",
            "dialog": {
                "title": "提示",
                "body": "这是个简单的弹框"
            }
        },
        {
            "type": "button",
            "label": "较大的弹框",
            "actionType": "dialog",
            "dialog": {
                "size": "lg",
                "title": "提示",
                "body": "这是个简单的弹框"
            }
        },
        {
            "type": "button",
            "label": "很大的弹框",
            "actionType": "dialog",
            "dialog": {
                "size": "xl",
                "title": "提示",
                "body": "这是个简单的弹框"
            }
        },
        {
            "type": "button",
            "label": "占满屏幕的弹框",
            "actionType": "dialog",
            "dialog": {
                "size": "full",
                "title": "全屏弹框",
                "body": "弹框尽可能占满，内容部分滚动。"
            }
        }
    ]
}
```

## 弹框与数据映射

默认弹框内由于数据链的存在，会自动映射父级同名变量，例如下例：

```schema: scope="body"
{
  "type": "crud",
  "api": "/api/mock2/sample",
  "draggable": true,
  "columns": [
    {
      "name": "id",
      "label": "ID"
    },
    {
      "name": "engine",
      "label": "Rendering engine"
    },
    {
      "name": "browser",
      "label": "Browser"
    },
    {
      "name": "platform",
      "label": "Platform(s)"
    },
    {
      "name": "version",
      "label": "Engine version"
    },
    {
      "name": "grade",
      "label": "CSS grade"
    },
    {
      "type": "button",
      "label": "一个弹框",
      "actionType": "dialog",
      "dialog": {
        "title": "一个弹框",
        "body": [
          {
            "type": "form",
            "api": "/api/mock2/sample/$id",
            "body": [
              {
                "type": "input-text",
                "name": "engine",
                "label": "Engine"
              }
            ]
          }
        ]
      }
    }
  ]
}
```

上例弹框中的表单项 `Engine` 会自动映射到父级数据中的 `engine` 变量，如果想调整当前特性，如你想调整父级映射变量的字段，可以利用[数据映射](../../docs/concepts/data-mapping)，例如：

```
/* Detailed source-code truncated for AI context efficiency. */
```

上例给 `dialog` 中配置 `data` 属性，可以将上层的 `engine` 变量映射为 `engine2`。请注意点击“新增”按钮后 dialog 内 form 的数据域会直接继承 CRUD 所在的数据域，如果 CRUD 过滤器中查询字段和 dialog 表单中的字段相同时，会错误的将外部数据映射到表单数据域内，需要配置数据映射将相关字段绑定的数据删除`{"&": "$$", "status": "__undefined"}`

## 多级弹框

```schema: scope="body"
{
    "type": "button",
    "label": "多级弹框",
    "actionType": "dialog",
    "dialog": {
        "title": "提示",
        "body": "这是个简单的弹框",
        "actions": [
            {
                "type": "button",
                "actionType": "confirm",
                "label": "确认",
                "primary": true
            },
            {
                "type": "button",
                "actionType": "dialog",
                "label": "再弹一个",
                "dialog": {
                    "title": "弹框中的弹框",
                    "body": "如果你想，可以无限弹下去",
                    "actions": [
                        {
                            "type": "button",
                            "actionType": "dialog",
                            "label": "来吧",
                            "level": "info",
                            "dialog": {
                                "title": "弹框中的弹框",
                                "body": "如果你想，可以无限弹下去",
                                "actions": [
                                    {
                                        "type": "button",
                                        "actionType": "confirm",
                                        "label": "不弹了",
                                        "primary": true
                                    }
                                ]
                            }
                        }
                    ]
                }
            }
        ]
    }
}
```

## 动作后关闭弹框

在弹框中配置行为按钮，可以在按钮上配置`"close": true`，在行为完成后，关闭当前弹框。

```schema: scope="body"
{
    "type": "button",
    "label": "弹个框",
    "actionType": "dialog",
    "dialog": {
        "title": "弹框",
        "body": [
          {
            "type": "button",
            "label": "默认的 ajax 请求",
            "actionType": "ajax",
            "api": "/api/mock2/form/saveForm?waitSeconds=1"
          },
          {
            "type": "button",
            "label": "ajax 请求成功后关闭弹框",
            "actionType": "ajax",
            "api": "/api/mock2/form/saveForm?waitSeconds=1",
            "close": true
          }
        ]
    }
}
```

以上例子是关闭当前弹窗，如果希望关闭上层弹窗，则需要给目标弹窗设置 `name` 属性，然后配置按钮 `close` 属性为目标 `name` 属性如：

```schema: scope="body"
{
    "type": "button",
    "label": "多级弹框",
    "actionType": "dialog",
    "dialog": {
        "title": "提示",
        "body": "这是个简单的弹框",
        "name": "dialog_1",
        "actions": [
            {
                "type": "button",
                "actionType": "confirm",
                "label": "确认",
                "primary": true
            },
            {
                "type": "button",
                "actionType": "dialog",
                "label": "再弹一个",
                "dialog": {
                    "title": "弹框中的弹框",
                    "body": "关闭当前弹窗的时候把外层的弹窗一起关了",
                    "actions": [
                        {
                            "type": "button",
                            "label": "关闭所有",
                            "level": "info",
                            "close": "dialog_1"
                        }
                    ]
                }
            }
        ]
    }
}
```

## 配置弹窗的按钮

默认弹窗会自动生成两个按钮，一个取消，一个确认。如果通过 `actions` 来自定义配置，则以配置的为准。

```schema: scope="body"
{
    "type": "button-toolbar",
    "buttons": [
        {
            "type": "button",
            "label": "无按钮",
            "actionType": "dialog",
            "dialog": {
                "title": "提示",
                "actions": [],
                "body": "无按钮的弹框"
            }
        },
        {
            "type": "button",
            "label": "只有一个确认按钮",
            "actionType": "dialog",
            "dialog": {
                "title": "提示",
                "actions": [{
                  "type": "button",
                  "actionType": "confirm",
                  "label": "OK",
                  "primary": true
                }],
                "body": "只有一个 OK 的弹框"
            }
        }
    ]
}
```

## 弹框中配置表单

### 基本使用

```schema: scope="body"
{
    "type": "button",
    "label": "弹个表单",
    "actionType": "dialog",
    "dialog": {
        "title": "在弹框中的表单",
        "body": {
            "type": "form",
            "api": "/api/mock2/form/saveForm?waitSeconds=2",
            "body": [
                {
                    "type": "input-text",
                    "name": "username",
                    "required": true,
                    "placeholder": "请输入用户名",
                    "label": "用户名"
                },
                {
                    "type": "input-password",
                    "name": "password",
                    "label": "密码",
                    "required": true,
                    "placeholder": "请输入密码"
                },
                {
                    "type": "checkbox",
                    "name": "rememberMe",
                    "label": "记住登录"
                }
            ]
        }
    }
}
```

### 提交表单 或 ajax 请求

弹框中通过配置`form`或`ajax`行为按钮，可以实现`form`提交和`ajax`请求操作。

```schema: scope="body"
{
    "type": "button",
    "label": "弹个表单",
    "actionType": "dialog",
    "dialog": {
        "title": "在弹框中的表单",
        "actions": [
            {
                "label": "提交表单",
                "actionType": "submit",
                "primary": true,
                "type": "button"
            },
            {
                "label": "ajax请求",
                "actionType": "ajax",
                "primary": true,
                "type": "button",
                "api": "/api/mock2/form/saveForm?waitSeconds=2"
            }
        ],
        "body": {
            "type": "form",
            "api": "/api/mock2/form/saveForm?waitSeconds=2",
            "body": [
                {
                    "type": "input-text",
                    "name": "text",
                    "required": true,
                    "label": "用户名",
                    "placeholder": "请输入用户名"
                },
                {
                    "type": "input-password",
                    "name": "password",
                    "label": "密码",
                    "placeholder": "请输入密码",
                    "required": true
                },
                {
                    "type": "checkbox",
                    "name": "rememberMe",
                    "label": "记住登录"
                }
            ]
        }
    }
}
```

### 提交表单 或 ajax 请求后不关闭弹框

默认情况下，当弹框中配置了 form 并进行了**提交表单操作（confirm）**或进行了**`ajax`请求**，请求成功后，会自动关闭当前弹框，你可以通过手动设置`"close": false` 来禁止该默认特性。

```schema: scope="body"
{
    "type": "button",
    "label": "弹个表单",
    "actionType": "dialog",
    "dialog": {
        "title": "在弹框中的表单",
        "actions": [
            {
                "label": "提交表单后不关闭",
                "actionType": "submit",
                "close": false,
                "primary": true,
                "type": "button"
            },
            {
                "label": "ajax请求后不关闭",
                "actionType": "ajax",
                "primary": true,
                "type": "button",
                "api": "/api/mock2/form/saveForm?waitSeconds=2"
            }
        ],
        "body": {
            "type": "form",
            "api": "/api/mock2/form/saveForm?waitSeconds=2",
            "body": [
                {
                    "type": "input-text",
                    "name": "text",
                    "required": true,
                    "label": "用户名",
                    "placeholder": "请输入用户名"
                },
                {
                    "type": "input-password",
                    "name": "password",
                    "label": "密码",
                    "required": true,
                    "placeholder": "请输入密码"
                },
                {
                    "type": "checkbox",
                    "name": "rememberMe",
                    "label": "记住登录"
                }
            ]
        }
    }
}
```

## feedback 反馈弹框

feedback 反馈弹框是指，在 ajax 请求后，可以显示一个弹框，进行反馈操作

### feedback 基本使用

```schema: scope="body"
{
    "type": "button",
    "label": "Feedback",
    "actionType": "ajax",
    "api": "/api/mock2/form/initData?waitSeconds=2",
    "tooltip": "点击我后会发送一个请求，请求回来后，弹出一个框。",
    "feedback": {
        "title": "操作成功",
        "body": "xxx 已操作成功"
    }
}
```

### 弹框中配置 feedback

#### 关闭 feedback 弹框时，同时关闭上层弹框

当你在弹框中配置了 feedback，操作之后，你希望关闭当前 feedback 弹框同时，关闭上层的弹框，具体有两种方式

##### 1. 不请求接口，直接关闭

`feedback`的`actions`中配置 `"actionType": "close"` 的按钮

```
/* Detailed source-code truncated for AI context efficiency. */
```

##### 2. 请求接口，请求成功后，关闭所有弹框

需要在 feedback 的 `body` 中添加 Form 组件，并配置`"actionType": "confirm"`，

```
/* Detailed source-code truncated for AI context efficiency. */
```

> 注意上面的例子：如果你的触发`feedback`的按钮`actionType`为`ajax`时，为需要额外在按钮上配置`"close": true`

#### 取消 feedback 弹框时，不同时关闭上层弹框

该场景只适用于**不请求接口关闭弹框**的场景，需要在 feedback 层添加`"skipRestOnCancel": true`

```schema: scope="body"
{
  "type": "button",
  "label": "弹一个框",
  "actionType": "dialog",
  "dialog": {
    "title": "提示",
    "body": {
      "type": "form",
      "api": "/api/mock2/form/initData?waitSeconds=1",
      "body": [
        {
          "type": "tpl",
          "tpl": "这是一个简单的弹框"
        }
      ]
    },
    "actions": [
      {
        "type": "button",
        "actionType": "confirm",
        "label": "Feedback",
        "feedback": {
          "body": "这是一个feedback弹框",
          "skipRestOnCancel": true,
          "actions": [
            {
              "type": "button",
              "actionType": "close",
              "label": "关闭"
            }
          ]
        }
      }
    ]
  }
}
```

#### 确认 feedback 弹框时，不同时关闭上层弹框

如果想让 feedback 弹框确认后，让之前触发这个 feedback 的按钮中断，那么需要配置 `skipRestOnConfirm`，这就意味着之前触发这个 feedback 的按钮必须重新提交一次。

### 根据条件显示 feedback

可以根据条件弹出，例如下面这个例子，只有当接口返回的时间戳可以整除 2 时才显示弹框。

```schema: scope="body"
{
    "type": "button",
    "label": "条件feedback",
    "actionType": "ajax",
    "api": "/api/mock2/form/initData?waitSeconds=1",
    "feedback": {
        "visibleOn": "!(this.date % 2)",
        "title": "操作成功",
        "body": "当前时间戳: <code>${date}</code>"
    }
}
```

## 配置 Esc 键和点击外部关闭弹框

可以通过配置 `closeOnEsc` 和 `closeOnOutside` 支持用 esc 键和点击其它区域关闭弹框。

```schema: scope="body"
{
    "label": "点击弹框",
    "type": "button",
    "actionType": "dialog",
    "dialog": {
      "closeOnEsc": true,
      "closeOnOutside": true,
      "title": "弹框标题",
      "body": [
        {
        "type": "input-text",
        "label": "更复杂的标签提示",
        "labelRemark": {
          "trigger": ["click"],
          "type": "remark",
          "title": "提示",
          "content": "<pre>first \nsecond\n${text1}</pre>"
        },
        "name": "text3"
      },
        {
          "label": "点击弹框2",
          "type": "button",
          "actionType": "dialog",
          "dialog": {
            "closeOnEsc": true,
            "closeOnOutside": true,
            "title": "弹框标题2",
            "body": "内容"
          }
        }
      ]
    }
}
```

## 属性表

| 属性名          | 类型                                      | 默认值             | 说明                                                                                             |
| --------------- | ----------------------------------------- | ------------------ | ------------------------------------------------------------------------------------------------ |
| type            | `string`                                  |                    | `"dialog"` 指定为 Dialog 渲染器                                                                  |
| title           | [SchemaNode](../../docs/types/schemanode) |                    | 弹出层标题                                                                                       |
| body            | [SchemaNode](../../docs/types/schemanode) |                    | 往 Dialog 内容区加内容                                                                           |
| size            | `string`                                  |                    | 指定 dialog 大小，支持: `xs`、`sm`、`md`、`lg`、`xl`、`full`、`custom`                           |
| width           | `number \| string`                        |                    | Dialog 宽度, size 为 `custom` 时生效                                                             |
| height          | `number \| string`                        |                    | Dialog 高度, size 为 `custom` 时生效                                                             |
| bodyClassName   | `string`                                  | `modal-body`       | Dialog body 区域的样式类名                                                                       |
| closeOnEsc      | `boolean`                                 | `false`            | 是否支持按 `Esc` 关闭 Dialog                                                                     |
| showCloseButton | `boolean`                                 | `true`             | 是否显示右上角的关闭按钮                                                                         |
| showErrorMsg    | `boolean`                                 | `true`             | 是否在弹框左下角显示报错信息                                                                     |
| showLoading     | `boolean`                                 | `true`             | 是否在弹框左下角显示 loading 动画                                                                |
| disabled        | `boolean`                                 | `false`            | 如果设置此属性，则该 Dialog 只读没有提交操作。                                                   |
| draggable       | `boolean`                                 |                    | 是否支持拖拽 Dialog                                                                              |
| actions         | Array<[Action](./action)>                 | 【确认】和【取消】 | 如果想不显示底部按钮，可以配置：`[]`                                                             |
| data            | `object`                                  |                    | 支持[数据映射](../../docs/concepts/data-mapping)，如果不设定将默认将触发按钮的上下文中继承数据。 |
|                 |

## 事件表

当前组件会对外派发以下事件，可以通过`onEvent`来监听这些事件，并通过`actions`来配置执行的动作，在`actions`中可以通过`${事件参数名}`或`${event.data.[事件参数名]}`来获取事件产生的数据，详细请查看[事件动作](../../docs/concepts/event-action)。

> `[name]`为当前数据域中的字段名，例如：当前数据域为 {username: 'amis'}，则可以通过${username}获取对应的值。

| 事件名称 | 事件参数                                                                 | 说明               |
| -------- | ------------------------------------------------------------------------ | ------------------ |
| confirm  | `event.data: object` 弹窗数据<br/>`[name]: any` 当前数据域中指定字段的值 | 点击确认提交时触发 |
| cancel   | `event.data: object` 弹窗数据<br/>`[name]: any` 当前数据域中指定字段的值 | 点击取消时触发     |

### confirm

```schema: scope="body"
[
  {
    "label": "弹个框",
    "type": "button",
    "onEvent": {
      "click": {
        "actions": [
          {
            "actionType": "dialog",
            "dialog": {
              "title": "一个弹框",
              "body": [
                {
                  "type": "alert",
                  "body": "试试点击确认按钮",
                  "level": "info",
                  "className": "mb-1"
                },
                {
                  "type": "form",
                  "title": "表单",
                  "debug": true,
                  "body": [
                    {
                      "label": "你的名字",
                      "type": "input-text",
                      "name": "name",
                      "id": "u:00ef9e3fe9db",
                      "mode": "horizontal",
                      "size": "md",
                      "value": "Amis"
                    }
                  ],
                  "id": "u:f4b2a90b685b"
                }
              ],
              "onEvent": {
                "confirm": {
                    "actions": [
                      {
                          "actionType": "toast",
                          "args": {
                              "msg": "你的名字是${name}"
                          }
                      }
                    ]
                }
              }
            }
          }
        ]
      }
    }
  }
]
```

### cancel

```schema: scope="body"
[
  {
    "label": "弹个框",
    "type": "button",
    "onEvent": {
      "click": {
        "actions": [
          {
            "actionType": "dialog",
            "dialog": {
              "title": "一个弹窗",
              "body": "试试点击取消按钮或者右上角的关闭",
              "onEvent": {
                "cancel": {
                    "actions": [
                    {
                        "actionType": "toast",
                        "args": {
                            "msg": "cancel"
                        }
                    }
                    ]
                }
              }
            }
          }
        ]
      }
    }
  }
]
```

## 动作表

当前组件对外暴露以下特性动作，其他组件可以通过指定`actionType: 动作名称`、`componentId: 该组件id`来触发这些动作，动作配置可以通过`args: {动作配置项名称: xxx}`来配置具体的参数，详细请查看[事件动作](../../docs/concepts/event-action#触发其他组件的动作)。

| 动作名称 | 动作配置                   | 说明         |
| -------- | -------------------------- | ------------ |
| confirm  | -                          | 确认（提交） |
| cancel   | -                          | 取消（关闭） |
| setValue | `value: object` 更新的数据 | 更新数据     |

### confirm 动作

```schema: scope="body"
{
    "type": "button",
    "label": "弹个表单",
    "actionType": "dialog",
    "dialog": {
        "title": "在弹框中的表单",
        "id": "dialog_confirm",
        "body": {
          "type": "form",
          "api": "/api/mock2/form/saveForm?waitSeconds=2",
          "body": [
              {
                  "type": "input-text",
                  "name": "username",
                  "required": true,
                  "placeholder": "请输入用户名",
                  "label": "用户名"
              },
              {
                  "type": "input-password",
                  "name": "password",
                  "label": "密码",
                  "required": true,
                  "placeholder": "请输入密码"
              },
              {
                  "type": "checkbox",
                  "name": "rememberMe",
                  "label": "记住登录"
              }
          ]
        },
        "actions": [
          {
            "type": "button",
            "label": "触发确认",
            "onEvent": {
              "click": {
                "actions": [
                  {
                    "actionType": "confirm",
                    "componentId": "dialog_confirm"
                  }
                ]
              }
            }
          }
        ]
    }
}
```

### cancel 动作

```schema: scope="body"
{
    "type": "button",
    "label": "弹个表单",
    "actionType": "dialog",
    "dialog": {
        "title": "在弹框中的表单",
        "id": "dialog_cancel",
        "body": {
          "type": "form",
          "api": "/api/mock2/form/saveForm?waitSeconds=2",
          "body": [
              {
                  "type": "input-text",
                  "name": "username",
                  "required": true,
                  "placeholder": "请输入用户名",
                  "label": "用户名"
              },
              {
                  "type": "input-password",
                  "name": "password",
                  "label": "密码",
                  "required": true,
                  "placeholder": "请输入密码"
              },
              {
                  "type": "checkbox",
                  "name": "rememberMe",
                  "label": "记住登录"
              }
          ]
        },
        "actions": [
          {
            "type": "button",
            "label": "触发取消",
            "onEvent": {
              "click": {
                "actions": [
                  {
                    "actionType": "cancel",
                    "componentId": "dialog_cancel"
                  }
                ]
              }
            }
          }
        ]
    }
}
```

### setValue 动作

通过`setValue`更新指定弹窗的数据。

#### 合并数据

默认`setValue`会将新数据与目标组件数据进行合并。

```
/* Detailed source-code truncated for AI context efficiency. */
```

#### 覆盖数据

可以通过`"dataMergeMode": "override"`来覆盖目标组件数据。

```
/* Detailed source-code truncated for AI context efficiency. */
```

---

### Zh CN Components Divider (`docs/zh-CN/components/divider.md`)

---
title: Divider 分割线
description:
type: 0
group: ⚙ 组件
menuName: Divider 分割线
icon:
order: 42
---

## 基本用法

```schema: scope="body"
{
    "type": "divider"
}
```

## 不同样式

```schema: scope="body"
[
    {
        "type": "divider",
        "lineStyle": "solid"
    },
    {
        "type": "divider",
        "lineStyle": "dashed"
    }
]
```

## 带标题的分割线

> `3.5.0`及以上版本

```schema: scope="body"
[
    {
        "type": "divider",
        "title": "Text",
        "titlePosition": "left"
    },
    {
        "type": "divider",
        "title": "Text",
        "titlePosition": "center"
    },
    {
        "type": "divider",
        "title": "Text",
        "titlePosition": "right"
    }
]
```

## 属性表

| 属性名    | 类型     | 默认值       | 说明                                       |    版本    |
| --------- | -------- | ------------ | --------------------------------------- |---------- |
| type      | `string` |              | `"divider"` 指定为 分割线 渲染器           |
| className | `string` |              | 外层 Dom 的类名                            |
| lineStyle | `string` | `solid`      | 分割线的样式，支持`dashed`和`solid`        |
| direction | `string` | `horizontal` | 分割线的方向，支持`horizontal`和`vertical` |     `3.5.0` |
| color     | `string` |              | 分割线的颜色                               |     `3.5.0` |
| rotate    | `number` |              | 分割线的旋转角度                           |     `3.5.0` |
| title     | [SchemaNode](../../docs/types/schemanode) |    |    分割线的标题    |      `3.5.0` |
| titleClassName | `string` |         | 分割线的标题类名                           |      `3.5.0` |        
| titlePosition    | `string` | `center`| 分割线的标题位置，支持`left`、`center`和`right` | `3.5.0` |

---

### Zh CN Components Drawer (`docs/zh-CN/components/drawer.md`)

---
title: Drawer 抽屉
description:
type: 0
group: ⚙ 组件
menuName: Drawer 抽屉
icon:
order: 43
---

## 基本用法

```schema: scope="body"
{
    "label": "弹出",
    "type": "button",
    "actionType": "drawer",
    "drawer": {
        "title": "抽屉标题",
        "body": "这是一个抽屉"
    }
}
```

## 多级弹框

可以嵌套使用。

```schema: scope="body"
{
    "type": "button",
    "label": "多级抽屉",
    "actionType": "drawer",
    "drawer": {
        "title": "提示",
        "body": "这是个简单的抽屉",
        "actions": [
            {
                "type": "button",
                "actionType": "confirm",
                "label": "确认",
                "primary": true
            },
            {
                "type": "button",
                "actionType": "drawer",
                "label": "再弹一个",
                "drawer": {
                    "title": "抽屉中的抽屉",
                    "body": "如果你想，可以继续弹下去",
                    "actions": [
                        {
                            "type": "button",
                            "actionType": "drawer",
                            "label": "来吧",
                            "level": "info",
                            "drawer": {
                                "title": "抽屉中的抽屉",
                                "body": "如果你想，可以无限弹下去",
                                "actions": [
                                    {
                                        "type": "button",
                                        "actionType": "confirm",
                                        "label": "不弹了",
                                        "primary": true
                                    }
                                ]
                            }
                        }
                    ]
                }
            }
        ]
    }
}
```

## 指定弹出方向

通过配置 `position`，可以指定抽屉弹出的方向，可选 `left`、`right`、`top` 和 `bottom`。默认为 `right`。

```schema: scope="body"
{
    "type": "button-toolbar",
    "buttons": [
        {
            "type": "button",
            "label": "左侧弹出",
            "actionType": "drawer",
            "drawer": {
                "position": "left",
                "title": "提示",
                "body": "这是一个从左侧弹出的抽屉"
            }
        },
        {
            "type": "button",
            "label": "右侧弹出",
            "actionType": "drawer",
            "drawer": {
                "position": "right",
                "title": "提示",
                "body": "这是一个从右侧弹出的抽屉"
            }
        },
        {
            "type": "button",
            "label": "顶部弹出",
            "actionType": "drawer",
            "drawer": {
                "position": "top",
                "title": "提示",
                "body": "这是一个从顶部弹出的抽屉"
            }
        },
        {
            "type": "button",
            "label": "底部弹出",
            "actionType": "drawer",
            "drawer": {
                "position": "bottom",
                "title": "提示",
                "body": "这是一个从底部弹出的抽屉"
            }
        }
    ]
}
```

## 抽屉尺寸

通过设置 `size` 来控制抽屉的大小，可选值：`xs`、`sm`、`md`、`lg` 和 `xl`。

```schema: scope="body"
{
    "type": "button-toolbar",
    "buttons": [
        {
            "type": "button",
            "label": "极小框",
            "actionType": "drawer",
            "drawer": {
                "size": "xs",
                "title": "提示",
                "body": "这是一个极小的抽屉"
            }
        },
        {
            "type": "button",
            "label": "小框",
            "actionType": "drawer",
            "drawer": {
                "size": "sm",
                "title": "提示",
                "body": "这是一个小抽屉"
            }
        },
        {
            "type": "button",
            "label": "中框",
            "actionType": "drawer",
            "drawer": {
                "size": "md",
                "title": "提示",
                "body": "这是一个标准的抽屉"
            }
        },
        {
            "type": "button",
            "label": "大框",
            "actionType": "drawer",
            "drawer": {
                "size": "lg",
                "title": "提示",
                "body": "这是一个大抽屉"
            }
        },
        {
            "type": "button",
            "label": "超大框",
            "actionType": "drawer",
            "drawer": {
                "size": "xl",
                "title": "提示",
                "body": "这是一个超大的抽屉"
            }
        },
    ]
}
```

## 自定义抽屉尺寸

通过设置 `width`（`position` 为 `left` 或 `right` 时生效）和 `height`（`position` 为 `top` 或 `bottom` 时生效）来控制抽屉的尺寸。

值如果是数字类型，单位默认使用 `px`, 如果是字符串类型，可以使用自定义 css 宽度变量，如：`%`、`vw`、`px` 等。

```schema: scope="body"
{
    "type": "button-toolbar",
    "buttons": [
        {
            "type": "button",
            "label": "自定义宽度",
            "actionType": "drawer",
            "drawer": {
                "position": "right",
                "width": 300,
                "title": "提示",
                "body": "这是一个自定义 300px 宽度的抽屉"
            }
        },
        {
            "type": "button",
            "label": "自定义高度",
            "actionType": "drawer",
            "drawer": {
                "position": "bottom",
                "height": 300,
                "title": "提示",
                "body": "这是一个自定义 300px 高度的抽屉"
            }
        }
    ]
}
```

## 可拖拽抽屉大小

配置 `"resizable": true`，可以拖拽调整 `drawer` 大小。

```schema: scope="body"
{
    "type": "button",
    "label": "可拖拽调整大小",
    "actionType": "drawer",
    "drawer": {
        "resizable": true,
        "title": "提示",
        "body": "这是一个可拖拽的抽屉"
    }
}
```

## 是否展示关闭按钮

配置 `"showCloseButton": false`，可以隐藏关闭按钮。

```schema: scope="body"
{
    "type": "button",
    "label": "无关闭按钮",
    "actionType": "drawer",
    "drawer": {
        "title": "提示",
        "body": "这是一个没有关闭按钮的抽屉",
        "showCloseButton": false
    }
}
```

## 蒙层显示

通过配置 `overlay`，来控制是否显示蒙层。默认为 `true`。

```schema: scope="body"
{
    "type": "button-toolbar",
    "buttons": [
        {
            "type": "button",
            "label": "默认",
            "actionType": "drawer",
            "drawer": {
                "overlay": true,
                "title": "提示",
                "body": "这是一个有蒙层的抽屉"
            }
        },
        {
            "type": "button",
            "label": "不显示",
            "actionType": "drawer",
            "drawer": {
                "overlay": false,
                "title": "提示",
                "body": "这是一个没有蒙层的抽屉"
            }
        }
    ]
}
```

## 关闭方式

通过配置 `closeOnOutside`，即可在点击抽屉外部时，直接关闭抽屉。

同时可以配置 `closeOnEsc`，让抽屉支持 <kbd>Esc</kbd> 键关闭。

```schema: scope="body"
{
    "type": "button-toolbar",
    "buttons": [
        {
            "type": "button",
            "label": "点击抽屉外自动关闭（有蒙层）",
            "actionType": "drawer",
            "drawer": {
                "closeOnOutside": true,
                "title": "提示",
                "body": "这是一个简单的抽屉"
            }
        },
        {
            "type": "button",
            "label": "点击抽屉外自动关闭（无蒙层）",
            "actionType": "drawer",
            "drawer": {
                "overlay": false,
                "closeOnOutside": true,
                "title": "提示",
                "body": "这是一个简单的抽屉"
            }
        },
        {
            "type": "button",
            "label": "按键关闭",
            "actionType": "drawer",
            "drawer": {
                "closeOnEsc": true,
                "title": "提示",
                "body": "试试按下 Esc"
            }
        }
    ]
}
```

## 动作后关闭抽屉

在抽屉中配置行为按钮，可以在按钮上配置 `"close": true`，在行为完成后，关闭当前抽屉。

```schema: scope="body"
{
    "type": "button",
    "label": "打开",
    "actionType": "drawer",
    "drawer": {
        "title": "提示",
        "body": [
            {
                "type": "button-toolbar",
                "buttons": [
                    {
                        "type": "button",
                        "label": "默认的 ajax 请求",
                        "actionType": "ajax",
                        "api": "/api/mock2/form/saveForm?waitSeconds=1"
                    },
                    {
                        "type": "button",
                        "label": "ajax 请求成功后关闭抽屉",
                        "actionType": "ajax",
                        "api": "/api/mock2/form/saveForm?waitSeconds=1",
                        "close": true
                    }
                ]
            }
        ]
    }
}
```

以上例子是关闭当前抽屉，如果希望关闭上层抽屉，则需要给目标抽屉设置 `name` 属性，然后配置按钮 `close` 属性为目标 `name` 属性如：

```schema: scope="body"
{
    "type": "button",
    "label": "多级抽屉",
    "actionType": "drawer",
    "drawer": {
        "title": "提示",
        "body": "这是个简单的抽屉",
        "name": "drawer_1",
        "actions": [
            {
                "type": "button",
                "actionType": "confirm",
                "label": "确认",
                "primary": true
            },
            {
                "type": "button",
                "actionType": "drawer",
                "label": "再弹一个",
                "drawer": {
                    "title": "抽屉中的抽屉",
                    "body": "关闭当前抽屉时，将外层抽屉一并关闭",
                    "actions": [
                        {
                            "type": "button",
                            "label": "关闭所有",
                            "level": "info",
                            "close": "drawer_1"
                        }
                    ]
                }
            }
        ]
    }
}
```

> 3.3.0 及以上版本

如果是表单，可以在表单上配置 `close: false`。

```schema: scope="body"
{
    "type": "button",
    "label": "弹个框",
    "actionType": "drawer",
    "drawer": {
        "type": "form",
        "api": "/api/mock2/form/saveForm",
        "body": [
            {
                "type": "input-text",
                "name": "name",
                "label": "姓名"
            }
        ],
        "close": false
    }
}
```

## 配置抽屉的按钮

默认抽屉会自动生成两个按钮，一个取消，一个确认。如果通过 `actions` 来自定义配置，则以配置的为准。

```schema: scope="body"
{
    "type": "button-toolbar",
    "buttons": [
        {
            "type": "button",
            "label": "无按钮",
            "actionType": "drawer",
            "drawer": {
                "title": "提示",
                "body": "这是一个没有按钮的抽屉",
                "actions": []
            }
        },
        {
            "type": "button",
            "label": "一个按钮",
            "actionType": "drawer",
            "drawer": {
                "title": "提示",
                "body": "只有一个 OK 的抽屉",
                "actions": [
                    {
                        "type": "button",
                        "actionType": "confirm",
                        "label": "OK",
                        "primary": true
                    }
                ]
            }
        }
    ]
}
```

## 属性表

| 属性名          | 类型                                      | 默认值             | 说明                                                                                              |
| --------------- | ----------------------------------------- | ------------------ | ------------------------------------------------------------------------------------------------- |
| type            | `string`                                  |                    | `"drawer"` 指定为 Drawer 渲染器                                                                   |
| title           | [SchemaNode](../../docs/types/schemanode) |                    | 弹出层标题                                                                                        |
| body            | [SchemaNode](../../docs/types/schemanode) |                    | 往 Drawer 内容区加内容                                                                            |
| size            | `string`                                  |                    | 指定 Drawer 大小，支持: `xs`、`sm`、`md`、`lg`、`xl`                                              |
| position        | `string`                                  | `right`            | 指定 Drawer 方向，支持: `left`、`right`、`top`、`bottom`                                          |
| className       | `string`                                  |                    | Drawer 最外层容器的样式类名                                                                       |
| headerClassName | `string`                                  |                    | Drawer 头部 区域的样式类名                                                                        |
| bodyClassName   | `string`                                  | `modal-body`       | Drawer body 区域的样式类名                                                                        |
| footerClassName | `string`                                  |                    | Drawer 页脚 区域的样式类名                                                                        |
| showCloseButton | `boolean`                                 | `true`             | 是否展示关闭按钮，当值为 `false` 时，默认开启 closeOnOutside                                      |
| closeOnEsc      | `boolean`                                 | `false`            | 是否支持按 <kbd>Esc</kbd> 关闭 Drawer                                                             |
| closeOnOutside  | `boolean`                                 | `false`            | 点击内容区外是否关闭 Drawer                                                                       |
| overlay         | `boolean`                                 | `true`             | 是否显示蒙层                                                                                      |
| resizable       | `boolean`                                 | `false`            | 是否可通过拖拽改变 Drawer 大小                                                                    |
| width           | `string \| number`                        | `500px`            | 容器的宽度，在 `position` 为 `left` 或 `right` 时生效                                             |
| height          | `string \| number`                        | `500px`            | 容器的高度，在 `position` 为 `top` 或 `bottom` 时生效                                             |
| actions         | Array<[Action](./action)>                 | 【确认】和【取消】 | 可以不设置，默认只有两个按钮。                                                                    |
| data            | `object`                                  |                    | 支持 [数据映射](../../docs/concepts/data-mapping)，如果不设定将默认将触发按钮的上下文中继承数据。 |

## 事件表

当前组件会对外派发以下事件，可以通过 `onEvent` 来监听这些事件，并通过 `actions` 来配置执行的动作，在 `actions` 中可以通过 `${事件参数名}` 或 `${event.data.[事件参数名]}` 来获取事件产生的数据，详细请查看[事件动作](../../docs/concepts/event-action)。

| 事件名称 | 事件参数                                                                 | 说明               |
| -------- | ------------------------------------------------------------------------ | ------------------ |
| confirm  | `event.data: object` 抽屉数据<br/>`[name]: any` 当前数据域中指定字段的值 | 点击确认提交时触发 |
| cancel   | `event.data: object` 抽屉数据<br/>`[name]: any` 当前数据域中指定字段的值 | 点击取消时触发     |

### confirm

```schema: scope="body"
[
  {
    "label": "打开",
    "type": "button",
    "onEvent": {
      "click": {
        "actions": [
          {
            "actionType": "drawer",
            "drawer": {
              "title": "标题",
              "body": "这是一个抽屉",
              "onEvent": {
                "confirm": {
                  "actions": [
                    {
                      "actionType": "toast",
                      "args": {
                        "msg": "confirm"
                      }
                    }
                  ]
                }
              }
            }
          }
        ]
      }
    }
  }
]
```

### cancel

```schema: scope="body"
[
  {
    "label": "打开",
    "type": "button",
    "onEvent": {
      "click": {
        "actions": [
          {
            "actionType": "drawer",
            "drawer": {
              "title": "标题",
              "body": "这是一个抽屉",
              "onEvent": {
                "cancel": {
                  "actions": [
                    {
                      "actionType": "toast",
                      "args": {
                        "msg": "cancel"
                      }
                    }
                  ]
                }
              }
            }
          }
        ]
      }
    }
  }
]
```

## 动作表

当前组件对外暴露以下特性动作，其他组件可以通过指定 `actionType: 动作名称`、`componentId: 该组件id` 来触发这些动作，动作配置可以通过 `args: {动作配置项名称: xxx}` 来配置具体的参数，详细请查看[事件动作](../../docs/concepts/event-action#触发其他组件的动作)。

| 动作名称 | 动作配置                   | 说明         |
| -------- | -------------------------- | ------------ |
| confirm  | -                          | 确认（提交） |
| cancel   | -                          | 取消（关闭） |
| setValue | `value: object` 更新的数据 | 更新数据     |

### confirm 动作

```schema: scope="body"
{
  "type": "button",
  "label": "弹个表单",
  "actionType": "drawer",
  "drawer": {
    "title": "在抽屉中的表单",
    "id": "drawer_confirm",
    "body": {
      "type": "form",
      "api": "/api/mock2/form/saveForm?waitSeconds=2",
      "body": [
        {
          "type": "input-text",
          "name": "username",
          "required": true,
          "placeholder": "请输入用户名",
          "label": "用户名"
        },
        {
          "type": "input-password",
          "name": "password",
          "label": "密码",
          "required": true,
          "placeholder": "请输入密码"
        },
        {
          "type": "checkbox",
          "name": "rememberMe",
          "label": "记住登录"
        }
      ]
    },
    "actions": [
      {
        "type": "button",
        "label": "触发确认",
        "onEvent": {
          "click": {
            "actions": [
              {
                "actionType": "confirm",
                "componentId": "drawer_confirm"
              }
            ]
          }
        }
      }
    ]
  }
}
```

### cancel 动作

```schema: scope="body"
{
  "type": "button",
  "label": "弹个表单",
  "actionType": "drawer",
  "drawer": {
    "title": "在抽屉中的表单",
    "id": "drawer_cancel",
    "body": {
      "type": "form",
      "api": "/api/mock2/form/saveForm?waitSeconds=2",
      "body": [
          {
              "type": "input-text",
              "name": "username",
              "required": true,
              "placeholder": "请输入用户名",
              "label": "用户名"
          },
          {
              "type": "input-password",
              "name": "password",
              "label": "密码",
              "required": true,
              "placeholder": "请输入密码"
          },
          {
              "type": "checkbox",
              "name": "rememberMe",
              "label": "记住登录"
          }
      ]
    },
    "actions": [
      {
        "type": "button",
        "label": "触发取消",
        "onEvent": {
          "click": {
            "actions": [
              {
                "actionType": "cancel",
                "componentId": "drawer_cancel"
              }
            ]
          }
        }
      }
    ]
  }
}
```

### setValue 动作

通过 `setValue` 更新指定抽屉的数据。

#### 合并数据

默认 `setValue` 会将新数据与目标组件数据进行合并。

```
/* Detailed source-code truncated for AI context efficiency. */
```

#### 覆盖数据

可以通过 `"dataMergeMode": "override"` 来覆盖目标组件数据。

```
/* Detailed source-code truncated for AI context efficiency. */
```

---

### Zh CN Components Dropdown Button (`docs/zh-CN/components/dropdown-button.md`)

---
title: DropDownButton 下拉菜单
description:
type: 0
group: ⚙ 组件
menuName: DropDownButton
icon:
order: 44
---

## 基本用法

```schema
{
    "type": "page",
    "body": {
        "type": "dropdown-button",
        "label": "下拉菜单",
        "buttons": [
            {
                "type": "button",
                "label": "按钮1",
                "disabled": true
            },
            {
                "type": "button",
                "label": "按钮2"
            },
            {
                "type": "button",
                "label": "按钮3"
            }
        ]
    }
}
```

## 分组展示模式

配置`children`可以实现分组展示，分组标题支持配置`icon`。

> 1.5.7 及以上版本

```schema: scope="body"
{
    "type": "dropdown-button",
    "label": "下拉菜单",
    "buttons": [
        {
            "label": "RD",
            "icon": "fa fa-user",
            "children": [
                {
                    "type": "button",
                    "label": "前端FE"
                },
                {
                    "type": "button",
                    "label": "后端RD"
                }
            ]
        },
        {
            "label": "QA",
            "icon": "fa fa-user",
            "children": [
                {
                    "type": "button",
                    "label": "测试QA",
                },
                {
                    "type": "button",
                    "label": "交付测试DQA",
                    "disabled": true
                },
                {
                    "type": "divider"
                }
            ]
        },
        {
            "label": "Manager",
            "icon": "fa fa-user",
            "children": [
                {
                    "type": "button",
                    "label": "项目经理PM"
                },
                {
                    "type": "button",
                    "label": "项目管理中心PMO",
                    "visible": false
                }
            ]
        }
    ]
}
```

## 关闭下拉菜单

配置`"closeOnClick": true`可以实现点击按钮后自动关闭下拉菜单。

```schema
{
    "type": "page",
    "body": {
        "type": "dropdown-button",
        "label": "下拉菜单",
        "closeOnClick": true,
        "closeOnOutside": true,
        "buttons": [
            {
                "type": "button",
                "label": "按钮1",
                "disabled": true
            },
            {
                "type": "button",
                "label": "按钮2"
            },
            {
                "type": "button",
                "label": "按钮3"
            }
        ]
    }
}
```

## 触发方式

> 1.4.0 及以上版本

默认是点击鼠标触发，可以通过 `"trigger": "hover"` 配置为鼠标移上去后触发

```schema
{
    "type": "page",
    "body": {
        "type": "dropdown-button",
        "label": "下拉菜单",
        "trigger": "hover",
        "buttons": [
            {
                "type": "button",
                "label": "按钮1",
                "disabled": true
            },
            {
                "type": "button",
                "label": "按钮2"
            },
            {
                "type": "button",
                "label": "按钮3"
            }
        ]
    }
}
```

## 设置图标

通过 `icon` 可以设置左侧图标

```schema
{
    "type": "page",
    "body": {
        "type": "dropdown-button",
        "label": "下拉菜单",
        "trigger": "hover",
        "icon": "fa fa-home",
        "buttons": [
            {
                "type": "button",
                "label": "按钮1",
                "disabled": true
            },
            {
                "type": "button",
                "label": "按钮2"
            },
            {
                "type": "button",
                "label": "按钮3"
            }
        ]
    }
}
```

## 只显示图标

可以设置 `level` 及 `hideCaret` 来只显示图标，并配合 `tooltip` 来显示提示文字

```schema
{
    "type": "page",
    "body": {
        "type": "dropdown-button",
        "level": "link",
        "icon": "fa fa-ellipsis-h",
        "hideCaret": true,
        "tooltip": "提示",
        "buttons": [
            {
                "type": "button",
                "label": "按钮1",
                "disabled": true
            },
            {
                "type": "button",
                "label": "按钮2"
            },
            {
                "type": "button",
                "label": "按钮3"
            }
        ]
    }
}
```

## 设置右侧图标

> 1.5.0 及以上版本

通过 `rightIcon` 设置右侧图标，同时通过 `hideCaret` 隐藏右侧下拉图标

```schema
{
    "type": "page",
    "body": {
        "type": "dropdown-button",
        "label": "下拉菜单",
        "trigger": "hover",
        "rightIcon": "fa fa-ellipsis-v",
        "hideCaret": true,
        "buttons": [
            {
                "type": "button",
                "label": "按钮1",
                "disabled": true
            },
            {
                "type": "button",
                "label": "按钮2"
            },
            {
                "type": "button",
                "label": "按钮3"
            }
        ]
    }
}
```

## 属性表

| 属性名          | 类型                    | 默认值            | 说明                                      |
| --------------- | ----------------------- | ----------------- | ----------------------------------------- |
| type            | `string`                | `dropdown-button` | 类型                                      |
| label           | `string`                |                   | 按钮文本                                  |
| className       | `string`                |                   | 外层 CSS 类名                             |
| btnClassName    | `string`                |                   | 按钮 CSS 类名                             |
| menuClassName   | `string`                |                   | 下拉菜单 CSS 类名                         |
| block           | `boolean`               |                   | 块状样式                                  |
| size            | `string`                |                   | 尺寸，支持`'xs'`、`'sm'`、`'md'` 、`'lg'` |
| align           | `string`                |                   | 位置，可选`'left'`或`'right'`             |
| buttons         | `Array<DropdownButton>` |                   | 配置下拉按钮                              |
| iconOnly        | `boolean`               |                   | 只显示 icon                               |
| defaultIsOpened | `boolean`               |                   | 默认是否打开                              |
| closeOnOutside  | `boolean`               | `true`            | 点击外侧区域是否收起                      |
| closeOnClick    | `boolean`               | `false`           | 点击按钮后自动关闭下拉菜单                |
| trigger         | `click` 或 `hover`      | `click`           | 触发方式                                  |
| hideCaret       | `boolean`               | false             | 隐藏下拉图标                              |
| popOverContainerSelector       | `string`               |              | 弹出的下拉按钮放在哪个节点下                              |

## 事件表

当前组件会对外派发以下事件，可以通过`onEvent`来监听这些事件，并通过`actions`来配置执行的动作，在`actions`中可以通过`${事件参数名}`或`${event.data.[事件参数名]}`来获取事件产生的数据，详细请查看[事件动作](../../docs/concepts/event-action)。

| 事件名称   | 事件参数                     | 说明                                    |
| ---------- | ---------------------------- | --------------------------------------- |
| mouseenter | items: Array<DropdownButton> | 触发方式为 hover 模式下，鼠标移入时触发 |
| mouseleave | items: Array<DropdownButton> | 触发方式为 hover 模式下，鼠标移出时触发 |

### mouseenter

```schema: scope="body"
{
    "type": "dropdown-button",
    "label": "下拉按钮",
    "trigger": "hover",
    "onEvent": {
        "mouseenter": {
            "actions": [
                {
                    "actionType": "toast",
                    "args": {
                    "msgType": "info",
                    "msg": "mouseenter ${event.data.items.length}"
                    }
                }
            ]
        }
    },
    "buttons": [
        {
            "type": "button",
            "label": "按钮1"
        },
        {
            "type": "button",
            "label": "按钮2"
        }
    ]
}
```

### mouseleave

```schema: scope="body"
{
    "type": "dropdown-button",
    "label": "下拉按钮",
    "trigger": "hover",
    "onEvent": {
        "mouseleave": {
            "actions": [
                {
                    "actionType": "toast",
                    "args": {
                    "msgType": "info",
                    "msg": "mouseleave ${event.data.items.length}"
                    }
                }
            ]
        }
    },
    "buttons": [
        {
            "type": "button",
            "label": "按钮1"
        },
        {
            "type": "button",
            "label": "按钮2"
        }
    ]
}
```

## 动作表

暂无

---

### Zh CN Components Each (`docs/zh-CN/components/each.md`)

---
title: Each 循环渲染器
description:
type: 0
group: ⚙ 组件
menuName: Each 循环渲染器
icon:
order: 45
---

## 基本用法

通过 name 属性指定要循环的数组，items 属性指定循环的内容。

```schema: scope="page"
{
  "type": "page",
  "data": {
    "arr": ["A", "B", "C"]
  },
  "body": {
        "type": "each",
        "name": "arr",
        "items": {
            "type": "tpl",
            "tpl": "<span class='label label-default m-l-sm'>${item}</span> "
        }
    }
}
```

### 如果是对象数组

如果数组中的数据是对象，可以直接使用内部变量 xxx 来获取，或者通过 `item.xxxx`。另外能用 index 来获取数组索引。

> 如果成员对象本身也有名字为 index 的字段就会覆盖到，获取不到索引了，请查看「循环嵌套」的章节解决

```schema:height="160" scope="page"
{
  "type": "page",
  "data": {
    "arr": [{"name": "a"}, {"name": "b"}, {"name": "c"}]
  },
  "body": {
        "type": "each",
        "name": "arr",
        "items": {
            "type": "tpl",
            "tpl": "<span class='label label-default m-l-sm'>${name}:${index}</span> "
        }
    }
}
```

### 循环嵌套

如果存在嵌套使用，通过默认的 `item` 或者 `index` 始终是拿的最里面那层的信息，想要获取上层 each 的信息，则需要自定义 `itemKeyName` 和 `indexKeyName` 来指定字段名。

```schema:height="160" scope="page"
{
  "type": "page",
  "data": {
    "arr": [{"name": "a", "subList": ["a1", "a2"]}, {"name": "b", "subList": ["b1", "b2"]}, {"name": "c", "subList": ["c1", "c2"]}]
  },
  "body": {
        "type": "each",
        "name": "arr",
        "itemKeyName": "itemOutter",
        "indexKeyName": "indexOutter",
        "items": [
            {
                "type": "tpl",
                "inline": false,
                "tpl": "<span class='label label-default m-l-sm'>${name}:${index}</span> "
            },

            {
                "type": "each",
                "name": "subList",
                "items": [
                    {
                        "type": "tpl",
                        "tpl": "<span class='label label-default m-l-sm'>${itemOutter.name}-${item}:${indexOutter}-${index}</span> "
                    }
                ]
            }
        ]
    }
}
```

## 用作 Field 时

当用在 Table 的列配置 Column、List 的内容、Card 卡片的内容和表单的 Static-XXX 中时，可以设置`name`属性，映射同名变量，然后用可以通过 `item` 变量获取单项值

### Table 中的列类型

```schema: scope="body"
{
    "type": "table",
    "data": {
        "items": [
            {
                "id": "1",
                "each": ["A1", "B1", "C1"]
            },
            {
                "id": "2",
                "each": ["A2", "B2", "C2"]
            },
            {
                "id": "3",
                "each": []
            }
        ]
    },
    "columns": [
        {
            "name": "id",
            "label": "Id"
        },

        {
            "name": "each",
            "label": "循环",
            "type": "each",
            "placeholder": "暂无内容",
            "items": {
                "type": "tpl",
                "tpl": "<span class='label label-info m-l-sm'>${item}</span>"
            }
        }
    ]
}
```

List 的内容、Card 卡片的内容配置同上

### Form 中静态展示

```schema: scope="body"
{
    "type": "form",
    "data": {
        "each": ["A", "B", "C"]
    },
    "body": [
        {
            "type": "each",
            "label": "静态展示each",
            "name": "each",
            "items": {
                "type": "tpl",
                "tpl": "<span class='label label-info m-l-sm'>${item}</span>"
            }
        }
    ]
}
```

## 使用数据映射

```schema: scope="page"
{
  "type": "page",
  "data": {
    "arr": ["A", "B", "C"]
  },
  "body": {
        "type": "each",
        "source": "${arr}",
        "items": {
            "type": "tpl",
            "tpl": "<span class='label label-default m-l-sm'>${item}</span> "
        }
    }
}
```

`name` 的优先级会比 `source` 更高

## 动态表单项

> 3.5.0 版本开始支持

表单项支持通过表达式配置动态表单项，可结合 `each` 组件一起使用。

```schema: scope="page"
{
  "type": "page",
  "data": {
    "arr": ["A", "B", "C"]
  },
  "body": [
    {
        type: "form",
        debug: true,
        body: [
            {
                "type": "each",
                "source": "${arr}",
                "items": {
                    "type": "input-text",
                    "label": "Input${item}",
                    "name": "text${index}"
                }
            }
        ]
    }
  ]
}
```

## 属性表

| 属性名       | 类型     | 默认值   | 说明                                                                 |
| ------------ | -------- | -------- | -------------------------------------------------------------------- |
| type         | `string` | `"each"` | 指定为 Each 组件                                                     |
| value        | `array`  | `[]`     | 用于循环的值                                                         |
| name         | `string` |          | 获取数据域中变量                                                     |
| source       | `string` |          | 获取数据域中变量， 支持 [数据映射](../../docs/concepts/data-mapping) |
| items        | `object` |          | 使用`value`中的数据，循环输出渲染器。                                |
| placeholder  | `string` |          | 当 `value` 值不存在或为空数组时的占位文本                            |
| itemKeyName  | `string` | `item`   | 获取循环当前数组成员                                                 |
| indexKeyName | `string` | `index`  | 获取循环当前索引                                                     |

---

### Zh CN Components Flex (`docs/zh-CN/components/flex.md`)

---
title: Flex 布局
description:
type: 0
group: ⚙ 组件
menuName: Flex 布局
icon:
order: 47
---

Flex 布局是基于 CSS Flex 实现的布局效果，它比 Grid 和 HBox 对子节点位置的可控性更强，比用 CSS 类的方式更易用，并且默认使用水平垂直居中的对齐。

## 基本用法

```schema: scope="body"
{
  "type": "flex",
  "items": [{
      "style": {
          "backgroundColor": "#1A5CFF",
          "width": 100,
          "height": 50,
          "margin": 5
      },
      "type": "tpl",
      "tpl": ""
  }, {
      "style": {
          "backgroundColor": "#46C93A",
          "width": 100,
          "height": 50,
          "margin": 5
      },
      "type": "tpl",
      "tpl": ""
  }, {
      "style": {
          "backgroundColor": "#FF4757",
          "width": 100,
          "height": 50,
          "margin": 5
      },
      "type": "tpl",
      "tpl": ""
  }]
}
```

其中 `items` 里的每一个都可以是其他 amis 类型。

## 子节点水平分布

> 严格来说并不一定是水平，因为还能通过 direction 修改方向，不过这里为了简化就这么称呼了

可以通过 justify 控制水平分布方式，默认是 `center` 居中，其他几种的示例如下：

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 垂直方向位置

可以通过设置 `alignItems` 改变在子节点在垂直方向的位置，默认是 `center` 居中，其他几个常见设置请参考：

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 布局方向

默认是行的方式，可以通过 "direction": "column" 改成列的方式。

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 移动端支持

有时候希望在移动端有不同展现，比如将 `direction` 改成 `column`：

```schema: scope="body"
{
  "type": "flex",
  "mobile": {
    "direction": "column"
  },
  "items": [{
      "style": {
          "backgroundColor": "#1A5CFF",
          "width": 100,
          "height": 50,
          "margin": 5
      },
      "type": "tpl",
      "tpl": ""
  }, {
      "style": {
          "backgroundColor": "#46C93A",
          "width": 100,
          "height": 50,
          "margin": 5
      },
      "type": "tpl",
      "tpl": ""
  }, {
      "style": {
          "backgroundColor": "#FF4757",
          "width": 100,
          "height": 50,
          "margin": 5
      },
      "type": "tpl",
      "tpl": ""
  }]
}
```

其他关于移动端定制的细节请参考[这里](../docs/extend/mobile)。

## 属性表

| 属性名     | 类型                                   | 默认值 | 说明                                                                                                |
| ---------- | -------------------------------------- | ------ | --------------------------------------------------------------------------------------------------- |
| type       | `string`                               | `flex` | 指定为 Flex 渲染器                                                                                  |
| className  | `string`                               |        | css 类名                                                                                            |
| justify    | `string`                               |        | "start", "flex-start", "center", "end", "flex-end", "space-around", "space-between", "space-evenly" |
| alignItems | `string`                               |        | "stretch", "start", "flex-start", "flex-end", "end", "center", "baseline"                           |
| style      | `object`                               |        | 自定义样式                                                                                          |
| items[]    | [SchemaNode](../docs/types/schemanode) |        |

---

### Zh CN Components Grid 2d (`docs/zh-CN/components/grid-2d.md`)

---
title: Grid 2D 布局
description:
type: 0
group: ⚙ 组件
menuName: Grid 2D 组件
icon:
order: 47
---

Grid 2D 是一种二维布局方式，它可以更直观设置组件位置。

> Grid 2D 布局不支持 IE11

## 基本用法

```schema: scope="body"
{
  "type": "grid-2d",
  "grids": [
    {
      "x": 1,
      "y": 1,
      "h": 1,
      "w": 6,
      "gridClassName": "bg-green-300",
      "type": "tpl",
      "tpl": "[grid-1] x:1 y:1 h:1 w:6"
    },
    {
      "x": 7,
      "y": 1,
      "h": 1,
      "w": 6,
      "gridClassName": "bg-blue-300",
      "type": "tpl",
      "tpl": "[grid-2] x:7 y:1 h:1 w:6"
    },
    {
      "x": 1,
      "y": 2,
      "h": 2,
      "w": 4,
      "gridClassName": "bg-red-300",
      "type": "tpl",
      "tpl": "[grid-3] x:1 y:2 h:2 w:4"
    },
    {
      "x": 5,
      "y": 2,
      "h": 1,
      "w": 8,
      "gridClassName": "bg-purple-300",
      "type": "tpl",
      "tpl": "[grid-4] x:5 y:2 h:1 w:8"
    }
  ]
}
```

## 布局基础

`grids` 中可以是任意组件，这里为了简化使用 tpl 组件，通过 x/y/h/w 这四个属性来控制格子的位置和大小。

首先看下图示例，它就是前面基本用法的示例加上标注：



默认水平方向会平分为 12 列，可以通过 `cols` 来调整，比如只分为 3 栏。

先看 `[grid-1]`，它的 `x/y/h/w` 值分别是 `1,1,1,6`：

- `x,y` 决定这个格子的位置，`1,1` 就是最左上角的位置，如图所示
- `w` 代表宽度占几格，因为水平方向一共 12 列，所以 6 就意味着占水平空间一半
- `h` 代表高度占几格，默认每行高度可以使用 `rowHeight` 来控制，也可以设置 `height` 来单独控制这一行的高度

其它格子也可以参照这张图推理出来，比如 `[grid-2]` 起始 x 位置是 `7`，宽度是 6，因此它和 `[grid-]` 平分了第一行。

## 独立设置高宽

在上面的例子中格子的宽度是根据页面宽度平分，高度是固定的，但我们也可以单独改变某一行或某一列的高宽，方法是格子上的 `width` 和 `height` 值。

看下面这个例子

```schema: scope="body"
{
  "type": "grid-2d",
  "cols": 3,
  "grids": [
    {
      "x": 1,
      "y": 1,
      "h": 1,
      "w": 1,
      "width": 100,
      "gridClassName": "bg-green-300",
      "type": "tpl",
      "tpl": "[grid-1] x:1 y:1 h:1 w:1"
    },
    {
      "x": 2,
      "y": 1,
      "h": 1,
      "w": 1,
      "height": 100,
      "gridClassName": "bg-blue-300",
      "type": "tpl",
      "tpl": "[grid-2] x:2 y:1 h:1 w:1"
    },
    {
      "x": 3,
      "y": 1,
      "h": 1,
      "w": 1,
      "width": 100,
      "gridClassName": "bg-red-300",
      "type": "tpl",
      "tpl": "[grid-3] x:3 y:1 h:1 w:1"
    },
    {
      "x": 2,
      "y": 2,
      "h": 1,
      "w": 1,
      "gridClassName": "bg-purple-300",
      "type": "tpl",
      "tpl": "[grid-4] x:2 y:2 h:1 w:1"
    }
  ]
}
```

在这个例子中，首先通过 `cols` 设置了列数为 `3`，然后将 `[grid-1]` 和 `[grid-3]` 的 width 设置为 `100`，使得这两列的宽度都是 100，而页面剩下的宽度就全都留给了 `[grid-2]`。

而在 `[grid-2]` 中通过 `height` 设置了高度，使得这一行高度是 `100px`，而不是默认的 `50px`。

请注意：`width` 将影响一整列，`height` 将影响一整行。

## 自适应内容高度

如果格子内容高度不确定，想更具内容自动撑开，可以设置 `height` 为 `auto`。

```schema: scope="body"
{
  "type": "grid-2d",
  "cols": 3,
  "grids": [
    {
      "x": 2,
      "y": 1,
      "h": 1,
      "w": 1,
      "height": "auto",
      "gridClassName": "bg-blue-300",
      "type": "tpl",
      "tpl": "1</br>2</br>3</br>4</br>5</br>6</br>"
    }
  ]
}
```

## 格子间距 gap / rowGap

通过 grip 上的 gap 属性来控制间距，默认包含水平和垂直间距

```schema: scope="body"
{
  "type": "grid-2d",
  "gap": 10,
  "gapRow": 5,
  "grids": [
    {
      "x": 1,
      "y": 1,
      "h": 1,
      "w": 6,
      "gridClassName": "bg-green-300",
      "type": "tpl",
      "tpl": "[grid-1] x:1 y:1 h:1 w:6"
    },
    {
      "x": 7,
      "y": 1,
      "h": 1,
      "w": 6,
      "gridClassName": "bg-blue-300",
      "type": "tpl",
      "tpl": "[grid-2] x:7 y:1 h:1 w:6"
    },
    {
      "x": 1,
      "y": 2,
      "h": 2,
      "w": 4,
      "gridClassName": "bg-red-300",
      "type": "tpl",
      "tpl": "[grid-3] x:1 y:2 h:2 w:4"
    },
    {
      "x": 5,
      "y": 2,
      "h": 1,
      "w": 8,
      "gridClassName": "bg-purple-300",
      "type": "tpl",
      "tpl": "[grid-4] x:5 y:2 h:1 w:8"
    }
  ]
}
```

## 内容区域小于格子的摆放

默认情况下，格子的高宽会撑满对应区域的高宽，但有时候内容高宽比这个格子小，比如一张图片，如何将它在各种中居中显示？

看下面的例子

```schema: scope="body"
{
  "type": "grid-2d",
  "cols": 3,
  "grids": [
    {
      "x": 1,
      "y": 1,
      "h": 1,
      "w": 1,
      "gridClassName": "bg-green-300",
      "type": "tpl",
      "tpl": "[grid-1] x:1 y:1 h:1 w:1"
    },
    {
      "x": 2,
      "y": 1,
      "h": 1,
      "w": 1,
      "align": "center",
      "valign": "middle",
      "gridClassName": "bg-blue-300",
      "type": "tpl",
      "tpl": "hello"
    },
    {
      "x": 3,
      "y": 1,
      "h": 1,
      "w": 1,
      "gridClassName": "bg-red-300",
      "type": "tpl",
      "tpl": "[grid-3] x:3 y:1 h:1 w:1"
    }
  ]
}
```

在中间的格子中，我们设置了 `"align": "center"` 和 `"valign": "middle"`，就使得文字水平和垂直居中显示了。

## 属性表

| 属性名          | 类型                                      | 默认值    | 说明                            |
| --------------- | ----------------------------------------- | --------- | ------------------------------- |
| type            | `string`                                  | `grid-2d` | 指定为 Grid 2D 渲染器           |
| gridClassName   | `string`                                  |           | 外层 Dom 的类名                 |
| gap             | `int`/`string`                            | 0         | 格子间距，包括水平和垂直        |
| cols            | `int`                                     | 12        | 格子水平划分为几个区域          |
| rowHeight       | `int`                                     | 50        | 每个格子默认垂直高度            |
| rowGap          | `int`/`string`                            |           | 格子垂直间距                    |
| grids           | `Array`                                   |           | 格子集合                        |
| grids[x]        | [SchemaNode](../../docs/types/schemanode) |           | 格子可以是其他渲染器            |
| grids[x].x      | `int`                                     |           | 格子起始位置的横坐标            |
| grids[x].y      | `int`                                     |           | 格子起始位置的纵坐标            |
| grids[x].w      | `int`                                     |           | 格子横跨几个宽度                |
| grids[x].h      | `int`                                     |           | 格子横跨几个高度                |
| grids[x].width  | `int`/`string`/`auto`                     |           | 格子所在列的宽度                |
| grids[x].height | `int`/`string`/`auto`                     |           | 格子所在行的高度，可以设置 auto |
| grids[x].align  | `left`/`center`/`right`/`auto`            | `auto`    | 格子内容水平布局                |
| grids[x].valign | `top`/`bottom`/`middle`/`auto`            | `auto`    | 格子内容垂直布局                |

---

### Zh CN Components Grid Nav (`docs/zh-CN/components/grid-nav.md`)

---
title: GridNav 宫格导航
description:
type: 0
group: ⚙ 组件
menuName: GridNav 宫格导航
icon:
order: 54
---

宫格菜单导航，不支持配置初始化接口初始化数据域，所以需要搭配类似像`Service`、`Form`或`CRUD`这样的，具有配置接口初始化数据域功能的组件，或者手动进行数据域初始化，然后通过`source`属性，获取数据链中的数据，完成菜单展示。

## 基本用法

通过 source 关联上下文数据，或者通过 name 关联。

```schema
{
    "type": "page",
    "data": {
        "items": [
          {
            "icon": "https://aisuda-public-images.bj.bcebos.com/amis/icon-1.png",
            "text": "导航1"
          },
          {
            "icon": "https://aisuda-public-images.bj.bcebos.com/amis/icon-2.png",
            "text": "导航2"
          },
          {
            "icon": "https://aisuda-public-images.bj.bcebos.com/amis/icon-3.png",
            "text": "导航3"
          },
          {
            "icon": "https://aisuda-public-images.bj.bcebos.com/amis/icon-4.png",
            "text": "导航4"
          }
        ]
    },
    "body": [
        {
            "type": "grid-nav",
            "source": "${items}"
        },
        {
            "type": "divider"
        },
        {
            "type": "grid-nav",
            "name": "items"
        }
    ]
}
```

也可以静态展示，即不关联数据固定显示。

```schema
{
    "type": "page",
    "body": {
        "type": "grid-nav",
        "options": [
            {
                "icon": "https://aisuda-public-images.bj.bcebos.com/amis/icon-1.png",
                "text": "导航1"
            },
            {
                "icon": "https://aisuda-public-images.bj.bcebos.com/amis/icon-2.png",
                "text": "导航2"
            },
            {
                "icon": "https://aisuda-public-images.bj.bcebos.com/amis/icon-3.png",
                "text": "导航3"
            },
            {
                "icon": "https://aisuda-public-images.bj.bcebos.com/amis/icon-4.png",
                "text": "导航4"
            }
        ]
    }
}
```

## 自定义列数

默认一行展示四个格子，可以通过 `columnNum` 自定义列数

```schema
{
    "type": "page",
    "data": {
        "items": [
            {
                "icon": "https://aisuda-public-images.bj.bcebos.com/amis/icon-1.png",
                "text": "导航1"
            },
            {
                "icon": "https://aisuda-public-images.bj.bcebos.com/amis/icon-2.png",
                "text": "导航2"
            },
            {
                "icon": "https://aisuda-public-images.bj.bcebos.com/amis/icon-3.png",
                "text": "导航3"
            }
        ]
    },
    "body": {
        "type": "grid-nav",
        "columnNum": 3,
        "source": "${items}"
    }
}
```

## 正方形格子

设置 `square` 属性后，格子的高度会和宽度保持一致。

```schema
{
    "type": "page",
    "data": {
        "items": [
            {
                "icon": "https://aisuda-public-images.bj.bcebos.com/amis/icon-1.png",
                "text": "导航1"
            },
            {
                "icon": "https://aisuda-public-images.bj.bcebos.com/amis/icon-2.png",
                "text": "导航2"
            },
            {
                "icon": "https://aisuda-public-images.bj.bcebos.com/amis/icon-3.png",
                "text": "导航3"
            },
            {
                "icon": "https://aisuda-public-images.bj.bcebos.com/amis/icon-4.png",
                "text": "导航4"
            }
        ]
    },
    "body": {
        "type": "grid-nav",
        "source": "${items}",
        "square": true
    }
}
```

## 格子间距

通过 `gutter` 属性设置格子之间的距离。

```schema
{
    "type": "page",
    "data": {
        "items": [
            {
                "icon": "https://aisuda-public-images.bj.bcebos.com/amis/icon-1.png",
                "text": "导航1"
            },
            {
                "icon": "https://aisuda-public-images.bj.bcebos.com/amis/icon-2.png",
                "text": "导航2"
            },
            {
                "icon": "https://aisuda-public-images.bj.bcebos.com/amis/icon-3.png",
                "text": "导航3"
            },
            {
                "icon": "https://aisuda-public-images.bj.bcebos.com/amis/icon-4.png",
                "text": "导航4"
            }
        ]
    },
    "body": {
        "type": "grid-nav",
        "source": "${items}",
        "gutter": 20
    }
}
```

## 内容横排

将 `direction` 属性设置为 `horizontal`，可以让宫格的内容呈横向排列。

```schema
{
    "type": "page",
    "data": {
        "items": [
            {
                "icon": "https://aisuda-public-images.bj.bcebos.com/amis/icon-1.png",
                "text": "导航1"
            },
            {
                "icon": "https://aisuda-public-images.bj.bcebos.com/amis/icon-2.png",
                "text": "导航2"
            },
            {
                "icon": "https://aisuda-public-images.bj.bcebos.com/amis/icon-3.png",
                "text": "导航3"
            },
            {
                "icon": "https://aisuda-public-images.bj.bcebos.com/amis/icon-4.png",
                "text": "导航4"
            }
        ]
    },
    "body": {
        "type": "grid-nav",
        "direction": "horizontal",
        "source": "${items}"
    }
}
```

## 图标占比

设置 `iconRatio` 可以控制图标宽度占比，默认 60%，设置 1-100 的数字。

```schema
{
    "type": "page",
    "data": {
        "items": [
            {
                "icon": "https://aisuda-public-images.bj.bcebos.com/amis/icon-1.png",
                "text": "导航1"
            },
            {
                "icon": "https://aisuda-public-images.bj.bcebos.com/amis/icon-2.png",
                "text": "导航2"
            },
            {
                "icon": "https://aisuda-public-images.bj.bcebos.com/amis/icon-3.png",
                "text": "导航3"
            },
            {
                "icon": "https://aisuda-public-images.bj.bcebos.com/amis/icon-4.png",
                "text": "导航4"
            }
        ]
    },
    "body": {
        "type": "grid-nav",
        "iconRatio": "40",
        "source": "${items}"
    }
}
```

## 角标提示

设置 badge 属性后，会在图标右上角展示相应的角标，支持红点、数字、彩带模式。

```schema
{
    "type": "page",
    "data": {
        "items": [
            {
                "icon": "https://aisuda-public-images.bj.bcebos.com/amis/icon-1.png",
                "text": "导航1",
                "badge": {
                    "mode": "text",
                    "text": "10"
                }
            },
            {
                "icon": "https://aisuda-public-images.bj.bcebos.com/amis/icon-2.png",
                "text": "导航2",
                "badge": {
                    "mode": "dot"
                }
            },
            {
                "icon": "https://aisuda-public-images.bj.bcebos.com/amis/icon-3.png",
                "text": "导航3",
                "badge": {
                    "mode": "ribbon",
                    "text": "热销"
                }
            },
            {
                "icon": "https://aisuda-public-images.bj.bcebos.com/amis/icon-4.png",
                "text": "导航4"
            }
        ]
    },
    "body": {
        "type": "grid-nav",
        "source": "${items}",
        "border": false
    }
}
```

## 点击交互

设置 clickAction 属性支持通用点击交互，详见 [Action](./action) 配置

```schema
{
    "type": "page",
    "data": {
        "items": [
            {
                "icon": "https://aisuda-public-images.bj.bcebos.com/amis/icon-1.png",
                "text": "外部跳转",
                "link": "https://www.baidu.com",
                "blank": true
            },
            {
                "icon": "https://aisuda-public-images.bj.bcebos.com/amis/icon-2.png",
                "text": "弹框",
                "clickAction": {
                    "actionType": "dialog",
                    "dialog": {
                        "title": "弹框",
                        "body": "这是个简单的弹框。"
                    }
                }
            },
            {
                "icon": "https://aisuda-public-images.bj.bcebos.com/amis/icon-3.png",
                "text": "内部跳转",
                "link": "/docs/index"
            },
            {
                "icon": "https://aisuda-public-images.bj.bcebos.com/amis/icon-4.png",
                "text": "导航4"
            }
        ]
    },
    "body": {
        "type": "grid-nav",
        "source": "${items}",
        "border": false
    }
}
```

## 属性表

| 属性名              | 类型            | 默认值     | 说明                                                     |
| ------------------- | --------------- | ---------- | -------------------------------------------------------- |
| type                | `string`        | `grid-nav` |                                                          |
| className           | `string`        |            | 外层 CSS 类名                                            |
| itemClassName       | `string`        |            | 列表项 css 类名                                          |
| contentClassName    | `string`        |            | 列表项内容 css 类名                                      |
| value               | `Array<object>` |            | 图片数组                                                 |
| source              | `string`        |            | 数据源                                                   |
| square              | `boolean`       |            | 是否将列表项固定为正方形                                 |
| center              | `boolean`       | `true`     | 是否将列表项内容居中显示                                 |
| border              | `boolean`       | `true`     | 是否显示列表项边框                                       |
| gutter              | `number`        |            | 列表项之间的间距，默认单位为`px`                         |
| reverse             | `boolean`       |            | 是否调换图标和文本的位置                                 |
| iconRatio           | `number`        | 60         | 图标宽度占比，单位%                                      |
| direction           | `string`        | `vertical` | 列表项内容排列的方向，可选值为 `horizontal` 、`vertical` |
| columnNum           | `number`        | 4          | 列数                                                     |
| options.icon        | `string`        |            | 列表项图标                                               |
| options.text        | `string`        |            | 列表项文案                                               |
| options.badge       | `BadgeSchema`   |            | 列表项角标，详见 [Badge](./badge)                        |
| options.link        | `string`        |            | 内部页面路径或外部跳转 URL 地址，优先级高于 clickAction  |
| options.blank       | `boolean`       |            | 是否新页面打开，link 为 url 时有效                       |
| options.clickAction | `ActionSchema`  |            | 列表项点击交互 详见 [Action](./action)                   |

---

### Zh CN Components Grid (`docs/zh-CN/components/grid.md`)

---
title: Grid 水平分栏
description:
type: 0
group: ⚙ 组件
menuName: Grid 组件
icon:
order: 46
---

## 基本用法

默认会水平均分宽度

```schema: scope="body"
[
    {
        "type": "grid",
        "columns": [
            {
                "columnClassName": "bg-green-300",
                "body": [
                    {
                        "type": "plain",
                        "text": "第一栏"
                    }
                ]
            },
            {
                "columnClassName": "bg-blue-300",
                "body": [
                    {
                        "type": "plain",
                        "text": "第二栏"
                    }
                ]
            }
        ]
    },
    {
        "type": "grid",
        "className": "m-t",
        "columns": [
            {
                "columnClassName": "bg-green-300",
                "body": [
                    {
                        "type": "plain",
                        "text": "第一栏"
                    }
                ]
            },
            {
                "columnClassName": "bg-blue-300",
                "body": [
                    {
                        "type": "plain",
                        "text": "第二栏"
                    }
                ]
            },
            {
                "columnClassName": "bg-red-300",
                "body": [
                    {
                        "type": "plain",
                        "text": "第三栏"
                    }
                ]
            }
        ]
    }
]
```

## 响应式

通过 `md` 设置屏幕中等宽度（768px）情况下的分栏

```schema: scope="body"
[
    {
        "type": "grid",
        "className": "b-a bg-dark lter",
        "columns": [
            {

                "md": 0,
                "body": [
                    {
                        "type": "plain",
                        "text": "md: 3",
                        "className": "b-r"
                    }
                ]
            },

            {
                "md": 9,
                "body": [
                    {
                        "type": "plain",
                        "text": "md: 9"
                    }
                ]
            }
        ]
    }
]
```

## 属性表

| 属性名                     | 类型                                               | 默认值   | 说明                 |
| -------------------------- | -------------------------------------------------- | -------- | -------------------- |
| type                       | `string`                                           | `"grid"` | 指定为 Grid 渲染器   |
| className                  | `string`                                           |          | 外层 Dom 的类名      |
| gap                        | `'xs' \| 'sm' \| 'base' \| 'none' \| 'md' \| 'lg'` |          | 水平间距             |
| valign                     | `'top' \| 'middle' \| 'bottom' \| 'between'`       |          | 垂直对齐方式         |
| align                      | `'left' \| 'right' \| 'between' \| 'center'`       |          | 水平对齐方式         |
| columns                    | `Array`                                            |          | 列集合               |
| columns[x]                 | [SchemaNode](../../docs/types/schemanode)          |          | 成员可以是其他渲染器 |
| columns[x].xs              | `int` or "auto"                                    |          | 宽度占比： 1 - 12    |
| columns[x].columnClassName |                                                    |          | 列类名               |
| columns[x].sm              | `int` or "auto"                                    |          | 宽度占比： 1 - 12    |
| columns[x].md              | `int` or "auto"                                    |          | 宽度占比： 1 - 12    |
| columns[x].lg              | `int` or "auto"                                    |          | 宽度占比： 1 - 12    |
| columns[x].valign          | `'top' \| 'middle' \| 'bottom' \| 'between'`       |          | 当前列内容的垂直对齐 |

更多使用说明，请参看 [Grid Props](https://react-bootstrap.github.io/layout/grid/#col-props)

---

### Zh CN Components Hbox (`docs/zh-CN/components/hbox.md`)

---
title: HBox 布局
description:
type: 0
group: ⚙ 组件
menuName: HBox
icon:
order: 48
---

## 基本用法

```schema: scope="body"
[
    {
        "type": "hbox",
        "className": "b-a bg-dark lter",
        "columns": [
            {
                "type": "plain",
                "text": "Col A",
                "columnClassName": "wrapper-xs b-r"
            },

            "Col B"
        ]
    },

    {
        "type": "hbox",
        "className": "b-a m-t bg-dark lter",
        "columns": [
            {
                "type": "plain",
                "text": "w-md",
                "columnClassName": "w-md wrapper-xs bg-primary b-r"
            },
            "..."
        ]
    }
]
```

## 属性表

| 属性名                     | 类型                                               | 默认值         | 说明                 |
| -------------------------- | -------------------------------------------------- | -------------- | -------------------- |
| type                       | `string`                                           | `"hbox"`       | 指定为 HBox 渲染器   |
| className                  | `string`                                           |                | 外层 Dom 的类名      |
| gap                        | `'xs' \| 'sm' \| 'base' \| 'none' \| 'md' \| 'lg'` |                | 水平间距             |
| valign                     | `'top' \| 'middle' \| 'bottom' \| 'between'`       |                | 垂直对齐方式         |
| align                      | `'left' \| 'right' \| 'between' \| 'center'`       |                | 水平对齐方式         |
| columns                    | `Array`                                            |                | 列集合               |
| columns[x]                 | [SchemaNode](../../docs/types/schemanode)          |                | 成员可以是其他渲染器 |
| columns[x].columnClassName | `string`                                           | `"wrapper-xs"` | 列上类名             |
| columns[x].valign          | `'top' \| 'middle' \| 'bottom' \| 'between'`       |                | 当前列内容的垂直对齐 |

---

### Zh CN Components Html (`docs/zh-CN/components/html.md`)

---
title: Html
description:
type: 0
group: ⚙ 组件
menuName: Html
icon:
order: 49
---

## 基本用法

渲染一段 HTML

```schema
{
  "body": {
    "type": "html",
    "html": "支持 <code>Html</code>"
  }
}
```

> 当需要获取数据域中变量时，使用 [Tpl](./tpl) 。

---

### Zh CN Components Icon (`docs/zh-CN/components/icon.md`)

---
title: Icon 图标
description:
type: 0
group: ⚙ 组件
menuName: Icon
icon:
order: 50
---

> 在 React 项目中使用 Icon 需要引入 `@fortawesome/fontawesome-free`，然后在代码中 `import '@fortawesome/fontawesome-free/css/all.css'`，还有相关的 webpack 配置，具体请参考 [amis-react-starter](https://github.com/aisuda/amis-react-starter) 里的配置

## 基本使用

```schema
{
    "type": "page",
    "body": {
        "type": "icon",
        "icon": "cloud"
    }
}
```

## 颜色及大小调整

icon 基于字体实现，所以可以通过[文字颜色](../../../style/typography/text-color)或[大小](../../../style/typography/font-size)来控制它。

```schema
{
    "type": "page",
    "body": {
        "type": "icon",
        "icon": "cloud",
        "className": "text-info text-xl"
    }
}
```

## 使用图标链接

icon 还可以使用 URL 地址，可以从 [iconfont](https://www.iconfont.cn/) 等网站下载图表的 svg 文件上传到服务器，然后使用对应的地址，比如

```schema
{
    "type": "page",
    "body": {
        "type": "icon",
        "icon": "https://suda.cdn.bcebos.com/images%2F2021-01%2Fdiamond.svg"
    }
}
```

## 使用 v5/v6 版本的 fontawesome

`icon`默认支持[fontawesome v4](https://fontawesome.com/v4/icons/)，如果想要支持 v5 以及 v6 版本的 fontawesome 请设置`vendor`为空字符串。

### fontawesome v5 版本

v5 用 far/fas 等表示前缀，可参考官网[示例](https://fontawesome.com/v5/search?m=free)

```
/* Detailed source-code truncated for AI context efficiency. */
```

### fontawesome v6 版本

v6 用 fa-regular / fa-solid 等表示前缀，可参考官网[示例](https://fontawesome.com/search?m=free)

```schema
{
    "type":"page",
    "body":[
        {
            "type":"icon",
            "icon":"fa-regular fa-address-book",
            "vendor":""
        },
        {
            "type":"icon",
            "icon":"fa-solid fa-address-book",
            "vendor":""
        },
        {
            "type":"icon",
            "icon":"fa-regular fa-address-book",
            "vendor":"",
            "className": "text-info text-xl"
        },
        {
            "type":"icon",
            "icon":"fa-solid fa-address-book",
            "vendor":"",
            "className": "text-info text-xl"
        }
    ]
}
```

## 属性表

| 属性名    | 类型                                 | 默认值 | 说明                                                                                                                      |
| --------- | ------------------------------------ | ------ | ------------------------------------------------------------------------------------------------------------------------- |
| type      | `string`                             | `icon` | 指定组件类型                                                                                                              |
| className | `string`                             |        | 外层 CSS 类名                                                                                                             |
| icon      | [模板](../../docs/concepts/template) |        | icon 名称，支持 [fontawesome v4](https://fontawesome.com/v4/icons/) 或 通过 registerIcon 注册的 icon、或使用 url          |
| vendor    | `string`                             |        | icon 类型，默认为`fa`, 表示 fontawesome v4。也支持 iconfont, 如果是 fontawesome v5 以上版本或者其他框架可以设置为空字符串 |

## 事件表

> 2.6.1 及以上版本

当前组件会对外派发以下事件，可以通过`onEvent`来监听这些事件，并通过`actions`来配置执行的动作，在`actions`中可以通过`${事件参数名}`或`${event.data.[事件参数名]}`来获取事件产生的数据，详细查看[事件动作](../../docs/concepts/event-action)。

| 事件名称   | 事件参数 | 说明           |
| ---------- | -------- | -------------- |
| click      | -        | 点击时触发     |
| mouseenter | -        | 鼠标移入时触发 |
| mouseleave | -        | 鼠标移出时触发 |

### click

鼠标点击。可以尝试通过`${event.context.nativeEvent}`获取鼠标事件对象。

```schema: scope="body"
{
  "type": "icon",
  "icon": "cloud",
  "onEvent": {
    "click": {
      "actions": [
        {
          "actionType": "toast",
          "args": {
            "msgType": "info",
            "msg": "${event.context.nativeEvent.target.className}"
          }
        }
      ]
    }
  }
}
```

### mouseenter

鼠标移入。可以尝试通过`${event.context.nativeEvent}`获取鼠标事件对象。

```schema: scope="body"
{
  "type": "icon",
  "icon": "cloud",
  "onEvent": {
    "mouseenter": {
      "actions": [
        {
          "actionType": "toast",
          "args": {
            "msgType": "info",
            "msg": "${event.context.nativeEvent.type}"
          }
        }
      ]
    }
  }
}
```

### mouseleave

鼠标移出。可以尝试通过`${event.context.nativeEvent}`获取鼠标事件对象。

```schema: scope="body"
{
  "type": "icon",
  "icon": "cloud",
  "onEvent": {
    "mouseleave": {
      "actions": [
        {
          "actionType": "toast",
          "args": {
            "msgType": "info",
            "msg": "${event.context.nativeEvent.type}"
          }
        }
      ]
    }
  }
}
```

---

### Zh CN Components Iframe (`docs/zh-CN/components/iframe.md`)

---
title: iFrame
description:
type: 0
group: ⚙ 组件
menuName: iFrame
icon:
order: 51
---

## 基本使用

内嵌外部站点，可用 iframe 来实现。

```schema: scope="body"
{
    "type": "iframe",
    "src": "https://github.com/baidu/amis",
    "height": 300
}
```

## src 使用动态数据

### 数据域变量

> 1.1.6

```schema:
{
  "type": "page",
  "data": {
    "iframeSrc": "https://github.com/baidu/amis"
  },
  "body": {
    "type": "iframe",
    "src": "${iframeSrc}",
    "height": 300
  }
}
```

## 其它原生 iframe 属性

> 2.1.0 及以上版本

还支持以下原生 iframe 属性，具体配置项请[参考](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/iframe)。

- name
- allow
- sandbox
- referrerpolicy

## 支持 base64 格式

> 2.4.0 及以上版本

`src`属性支持传入符合 base64 编码标准的 [MIME 类型](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Basics_of_HTTP/MIME_types)字符串，具体效果参考[示例](../../../examples/iframe)

## 如何和 iframe 通信

#### amis 向 iframe 通信

在 iframe 页面中添加`message`事件监听器，在 iframe 初始化、更新或者接收到其他组件发送数据的时候，会通过 `postMessage` 发送当前数据域数据，iframe 页面的事件监听器中可以通过`e.data`进行获取：

```js
window.addEventListener('message', e => {
  // e.data 获取当前数据域数据，进行使用
});
```

`e.data` 格式及参数说明：

```json
{
  "type": "amis:init", // 当前事件类型
  "data": {
    //... 当前数据域数据
  }
}
```

- **type**: 当前事件类型
  - amis:init：初始化的时候触发
  - amis:update：组件更新时触发
  - amis:receive：组件通过 target 接收到其他组件发送来数据的时候
- **data**：当前数据源数据

> 如果是 webpack 开发环境，注意过滤掉`webpackOk`类型消息

#### iframe 页面向 amis 通信

可以通过以下两种方式实现 iframe 页面向 amis 通信：

- 方式一：通过 events 属性，基于[Action](./action)实现，有一定的局限性。
- 方式二：通过 onEvent 属性，基于[事件动作](../../docs/concepts/event-action)实现，更灵活。

> 注意：如果同时配置了 events 和 onEvent，amis 都会执行，且 onEvent 配置的动作行为会先于 events 执行。

步骤如下：

1. 在 iframe 页面中定义消息名称和需要传递的数据。获取父级 window，并使用`postMessage`传递数据，格式如下，：

```js
window.parent.postMessage(
  {
    type: 'amis:detail',
    data: {
      iframeId: '111'
    }
  },
  '*'
);
```

`message`格式：

- `type`: 标识要触发的 amis 行为，请使用 `amis:xxx` 的格式，这里我们设置为配置好的`detail`事件
- `data`: 传给 amis 的数据，amis 会将该数据与当前数据域进行合并进行使用

2. 在 amis 的 iframe 组件中指明需要监听的消息名称，以及需要执行的动作。

```json
// 方式一：即在 amis 的 iframe 配置项中配置 events 对象
{
  "type": "iframe",
  "src": "http://www.xxx.com",
  "events": {
    "detail": {
      "actionType": "dialog", // 弹窗动作
      "dialog": {
        "title": "弹框",
        "body": "iframe 传给 amis 的 id 是：${iframeId}" // 在弹框中渲染`"iframe 传给 amis 的 id 是：${iframeId}"`这段模板，即111
      }
    }
  }
}

// 方式二：即在 amis 的 iframe 配置项中配置 onEvent 对象
{
  "type": "iframe",
  "src": "http://www.xxx.com",
  "onEvent": {
    "detail": {
      "actions": [
        // 动作 1，弹窗动作
        {
          "actionType": "dialog",
          "dialog": {
            "title": "弹框",
            "body": "iframe 传给 amis 的 id 是：${iframeId}" // 在弹框中渲染`"iframe 传给 amis 的 id 是：${iframeId}"`这段模板，即111
          }
        },
        // 动作 2，触发指定组件的特性动作
        {
          "actionType": "crud",
          "componentId": "form01",
          "data": {
            "iframeId": "${iframeId}" // 刷新请求参数为`"iframe 传给 amis 的 id 是：${iframeId}"`这段模板，即111
          }
        }
      ]
    }
  }
}
```

## 设置高度自适应

默认 amis 中只支持给 iframe 配置固定高度，我们可以通过上面说到的通信机制实现高度自适应。

1. 首先在 iframe 页面中获取到页面高度
2. 通过`amis:resize`事件，将高度信息发送给 amis

```js
window.parent.postMessage(
  {
    type: 'amis:resize',
    data: {
      height: 400
    }
  },
  '*'
);
```

这样就可以动态设置 iframe 组件高度

## 属性表

| 属性名         | 类型               | 默认值     | 说明                 |
| -------------- | ------------------ | ---------- | -------------------- |
| type           | `string`           | `"iframe"` | 指定为 iFrame 渲染器 |
| className      | `string`           |            | iFrame 的类名        |
| frameBorder    | `Array`            |            | frameBorder          |
| style          | `object`           |            | 样式对象             |
| src            | `string`           |            | iframe 地址          |
| allow          | `string`           |            | allow 配置           |
| sandbox        | `string`           |            | sandbox 配置         |
| referrerpolicy | `string`           |            | referrerpolicy 配置  |
| height         | `number`或`string` | `"100%"`   | iframe 高度          |
| width          | `number`或`string` | `"100%"`   | iframe 宽度          |

---

### Zh CN Components Image (`docs/zh-CN/components/image.md`)

---
title: Image 图片
description:
type: 0
group: ⚙ 组件
menuName: Image 图片
icon:
order: 52
---

## 基本使用

```schema
{
    "type": "page",
    "body": {
        "type": "image",
        "src": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,w_216,l_1,f_jpg,q_80"
    }
}
```

也可以配置`name`属性关联上下文数据

```schema
{
    "type": "page",
    "data": {
        "imageUrl": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,w_216,l_1,f_jpg,q_80"
    },
    "body": {
        "type": "image",
        "name": "imageUrl"
    }
}
```

## 配置标题和说明

```schema
{
    "type": "page",
    "body": {
        "type": "image",
        "src": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,w_216,l_1,f_jpg,q_80",
        "title": "这是标题",
        "imageCaption": "这是一段说明"
    }
}
```

## 配置缩略图

### 显示模式

```schema: scope="body"
{
    "type": "form",
    "mode": "horizontal",
    "data": {
        "image": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,w_216,l_1,f_jpg,q_80"
    },
    "body": [
        {
            "type": "static-image",
            "name": "image",
            "label": "宽度占满",
            "thumbMode": "w-full"
        },
        {
            "type": "static-image",
            "name": "image",
            "label": "高度占满",
            "thumbMode": "h-full"
        },
        {
            "type": "static-image",
            "name": "image",
            "label": "颜色",
            "label": "默认",
            "thumbMode": "contain"
        },
        {
            "type": "static-image",
            "name": "image",
            "label": "覆盖",
            "thumbMode": "cover"
        }
    ]
}
```

### 显示比例

```schema: scope="body"
{
    "type": "form",
    "mode": "horizontal",
    "data": {
        "image": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,w_216,l_1,f_jpg,q_80"
    },
    "body": [
        {
            "type": "static-image",
            "name": "image",
            "label": "1比1",
            "thumbRatio": "1:1",
            "thumbMode": "cover"
        },
        {
            "type": "static-image",
            "name": "image",
            "label": "4比3",
            "thumbRatio": "4:3",
            "thumbMode": "cover"
        },
        {
            "type": "static-image",
            "name": "image",
            "label": "颜色",
            "label": "16比9",
            "thumbRatio": "16:9",
            "thumbMode": "cover"
        }
    ]
}
```

## 放大功能

配置`"enlargeAble": true`，鼠标移动到图片上会显示可点击图标，点击可放大展示

```schema
{
    "type": "page",
    "body": {
        "type": "image",
        "src": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,w_216,l_1,f_jpg,q_80",
        "enlargeAble": true
    }
}
```

在列表中，图片组件的放大模式下默认展示所有行的图片信息，设置`"enlargeWithGallary": true`效果相同。

```schema
{
    "type": "page",
    "data": {
        "imageList": [
            {
                "name": "amis",
                "image_url": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,w_216,l_1,f_jpg,q_80"
            },
            {
                "name": "amis",
                "image_url": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692942/d8e4992057f9.jpeg@s_0,w_216,l_1,f_jpg,q_80"
            },
            {
                "name": "tom",
                "image_url": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693148/1314a2a3d3f6.jpeg@s_0,w_216,l_1,f_jpg,q_80"
            },
            {
                "name": "jack",
                "image_url": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693379/8f2e79f82be0.jpeg@s_0,w_216,l_1,f_jpg,q_80"
            }
        ]
    },
    "body": {
    "type": "crud",
    "source": "${imageList}",
    "syncLocation": false,
    "columns": [
      {
        "name": "name",
        "label": "名称"
      },
      {
        "type": "image",
        "name": "image_url",
        "label": "图片",
        "enlargeAble": true
      }
    ]
  }
}
```

在列表中，图片组件配置`"enlargeWithGallary": false`可以关闭放大模式下图片集列表的展示。

```schema
{
    "type": "page",
    "data": {
        "imageList": [
            {
                "name": "amis",
                "image_url": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,w_216,l_1,f_jpg,q_80"
            },
            {
                "name": "amis",
                "image_url": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692942/d8e4992057f9.jpeg@s_0,w_216,l_1,f_jpg,q_80"
            },
            {
                "name": "tom",
                "image_url": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693148/1314a2a3d3f6.jpeg@s_0,w_216,l_1,f_jpg,q_80"
            },
            {
                "name": "jack",
                "image_url": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693379/8f2e79f82be0.jpeg@s_0,w_216,l_1,f_jpg,q_80"
            }
        ]
    },
    "body": {
    "type": "crud",
    "source": "${imageList}",
    "syncLocation": false,
    "columns": [
      {
        "name": "name",
        "label": "名称"
      },
      {
        "type": "image",
        "name": "image_url",
        "label": "图片",
        "enlargeAble": true,
        "enlargeWithGallary": false
      }
    ]
  }
}
```

可以配置`originalSrc`，来指定原图资源地址，作为放大预览的图片地址

```schema
{
    "type": "page",
    "body": {
        "type": "image",
        "src": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,w_216,l_1,f_jpg,q_80",
        "originalSrc": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg",
        "enlargeAble": true
    }
}
```

`enlargeTitle`和`enlargeCaption`可以配置放大预览中的标题和描述

```schema
{
    "type": "page",
    "body": {
        "type": "image",
        "src": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,w_216,l_1,f_jpg,q_80",
        "originalSrc": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg",
        "enlargeAble": true,
        "enlargeTitle": "这是一个标题",
        "enlargeCaption": "这是一段描述"
    }
}
```

## 设置高宽

通过 `width` 和 `height` 可以设置缩率图显示的高宽

```schema
{
    "type": "page",
    "body": {
        "type": "image",
        "width": "200px",
        "height": "200px",
        "src": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,w_400,l_1,f_jpg,q_80"
    }
}
```

## 原图模式

> 1.2.3 及以上版本

默认图片为缩略图模式，可以通过配置 imageMode: "original" 修改为原图模式，原图模式为块状展示，宽度尽可能占满。

```schema
{
    "type": "page",
    "data": {
        "imageUrl": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg"
    },
    "body": {
        "type": "image",
        "imageMode": "original",
        "name": "imageUrl",
        "title": "这是标题",
        "imageCaption": "这是一段说明"
    }
}
```

## 打开外部链接

> 1.3.3 及以上版本

可以设置 href 属性来支持图片点击打开链接，需要注意这和放大功能是冲突的，只能二选一。

```schema: scope="body"
{
    "type": "image",
    "src": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,w_216,l_1,f_jpg,q_80",
    "href": "https://github.com/baidu/amis"
}
```

href 也可以是模板

```schema
{
    "type": "page",
    "data": {
        "imageUrl": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg",
        "imageHref": "https://github.com/baidu/amis"
    },
    "body": {
        "type": "image",
        "name": "imageUrl",
        "href": "${imageHref}"
    }
}
```

## 用作 Field 时

当用在 Table 的列配置 Column、List 的内容、Card 卡片的内容和表单的 Static-XXX 中时，可以设置`name`属性，映射同名变量

### Table 中的列类型

```schema: scope="body"
{
    "type": "table",
    "data": {
        "items": [
            {
                "id": "1",
                "image": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,w_216,l_1,f_jpg,q_80"
            },
            {
                "id": "2",
                "image": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,w_216,l_1,f_jpg,q_80"
            },
            {
                "id": "3",
                "image": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,w_216,l_1,f_jpg,q_80"
            }
        ]
    },
    "columns": [
        {
            "name": "id",
            "label": "Id"
        },

        {
            "name": "image",
            "label": "图片",
            "type": "image"
        }
    ]
}
```

List 的内容、Card 卡片的内容配置同上

### Form 中静态展示

```schema: scope="body"
{
    "type": "form",
    "data": {
        "image": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,w_216,l_1,f_jpg,q_80"
    },
    "body": [
        {
            "type": "static-image",
            "name": "image",
            "label": "颜色",
            "innerClassName": "no-border"
        }
    ]
}
```

## 自定义点击行为

> 1.5.0 及以上版本

可以通过 `clickAction` 设置点击触发行为。

```schema: scope="body"
{
    "type": "image",
    "src": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,w_216,l_1,f_jpg,q_80",
    "class": "cursor-pointer",
    "clickAction": {
        "actionType": "dialog",
        "dialog": {
            "title": "弹框标题",
            "body": "这是一个弹框"
        }
    }
}
```

## 工具栏

> 2.2.0 及以上版本

配置`"showToolbar": true`使图片在放大模式下开启图片工具栏。配置`"toolbarActions"`属性可以自定义工具栏的展示方式，具体配置参考[ImageAction](./image#imageaction)

```schema
{
    "type": "page",
    "body": {
        "type": "image",
        "src": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,w_216,l_1,f_jpg,q_80",
        "enlargeAble": true,
        "showToolbar": true
    }
}
```

## 属性表

| 属性名             | 类型                                             | 默认值    | 说明                                                                                          | 版本    |
| ------------------ | ------------------------------------------------ | --------- | --------------------------------------------------------------------------------------------- | ------- |
| type               | `string`                                         |           | 如果在 Table、Card 和 List 中，为`"image"`；在 Form 中用作静态展示，为`"static-image"`        |
| className          | `string`                                         |           | 外层 CSS 类名                                                                                 |
| innerClassName     | `string`                                         |           | 组件内层 CSS 类名                                                                             |
| imageClassName     | `string`                                         |           | 图片 CSS 类名                                                                                 |
| thumbClassName     | `string`                                         |           | 图片缩率图 CSS 类名                                                                           |
| height             | `string`                                         |           | 图片缩率高度                                                                                  |
| width              | `string`                                         |           | 图片缩率宽度                                                                                  |
| title              | `string`                                         |           | 标题                                                                                          |
| imageCaption       | `string`                                         |           | 描述                                                                                          |
| placeholder        | `string`                                         |           | 占位文本                                                                                      |
| defaultImage       | `string`                                         |           | 无数据时显示的图片                                                                            |
| src                | `string`                                         |           | 缩略图地址                                                                                    |
| href               | [模板](../../docs/concepts/template)             |           | 外部链接地址                                                                                  |
| originalSrc        | `string`                                         |           | 原图地址                                                                                      |
| enlargeAble        | `boolean`                                        |           | 支持放大预览                                                                                  |
| enlargeTitle       | `string`                                         |           | 放大预览的标题                                                                                |
| enlargeCaption     | `string`                                         |           | 放大预览的描述                                                                                |
| enlargeWithGallary | `string`                                         | `true`    | 在表格中，图片的放大功能会默认展示所有图片信息，设置为`false`将关闭放大模式下图片集列表的展示 |
| thumbMode          | `string`                                         | `contain` | 预览图模式，可选：`'w-full'`, `'h-full'`, `'contain'`, `'cover'`                              |
| thumbRatio         | `string`                                         | `1:1`     | 预览图比例，可选：`'1:1'`, `'4:3'`, `'16:9'`                                                  |
| imageMode          | `string`                                         | `thumb`   | 图片展示模式，可选：`'thumb'`, `'original'` 即：缩略图模式 或者 原图模式                      |
| showToolbar        | `boolean`                                        | `false`   | 放大模式下是否展示图片的工具栏                                                                | `2.2.0` |
| toolbarActions     | `ImageAction[]`                                  |           | 图片工具栏，支持旋转，缩放，默认操作全部开启                                                  | `2.2.0` |
| maxScale           | `number` 或 [模板](../../docs/concepts/template) |           | 执行调整图片比例动作时的最大百分比                                                            | `3.4.4` |
| minScale           | `number` 或 [模板](../../docs/concepts/template) |           | 执行调整图片比例动作时的最小百分比                                                            | `3.4.4` |

#### ImageAction

```typescript
interface ImageAction {
  /* 操作key */
  key: 'rotateRight' | 'rotateLeft' | 'zoomIn' | 'zoomOut' | 'scaleOrigin';
  /* 动作名称 */
  label?: string;
  /* 动作icon */
  icon?: string;
  /* 动作自定义CSS类 */
  iconClassName?: string;
  /* 动作是否禁用 */
  disabled?: boolean;
}
```

## 事件表

当前组件会对外派发以下事件，可以通过`onEvent`来监听这些事件，并通过`actions`来配置执行的动作，在`actions`中可以通过`${事件参数名}`或`${event.data.[事件参数名]}`来获取事件产生的数据，详细查看[事件动作](../../docs/concepts/event-action)。

| 事件名称   | 事件参数   | 说明           |
| ---------- | ---------- | -------------- |
| click      | 上下文数据 | 点击图片时触发 |
| mouseenter | 上下文数据 | 鼠标移入时触发 |
| mouseleave | 上下文数据 | 鼠标移入时触发 |

### click / mouseenter / mouseleave

点击图片 / 鼠标移入图片 / 鼠标移出图片，可以尝试通过${event.context.nativeEvent}获取鼠标事件对象。

```schema: scope="body"
{
    "type": "image",
    "src": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,w_216,l_1,f_jpg,q_80",
    "onEvent": {
        "click": {
            "actions": [
                {
                    "actionType": "toast",
                    "args": {
                        "msg": "图片被点击了"
                    }
                }
            ]
        },
        "mouseenter": {
            "actions": [
                {
                    "actionType": "toast",
                    "args": {
                        "msg": "鼠标移入图片"
                    }
                }
            ]
        },
        "mouseleave": {
            "actions": [
                {
                    "actionType": "toast",
                    "args": {
                        "msg": "鼠标移出图片"
                    }
                }
            ]
        }
    }
}
```

## 动作表

当前组件对外暴露以下特性动作，其他组件可以通过指定`actionType: 动作名称`、`componentId: 该组件id`来触发这些动作，动作配置可以通过`args: {动作配置项名称: xxx}`来配置具体的参数，详细请查看[事件动作](../../docs/concepts/event-action#触发其他组件的动作)。

| 动作名称 | 动作配置                                                                                                                              | 说明                                 |
| -------- | ------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ |
| preview  | -                                                                                                                                     | 预览图片                             |
| zoom     | `scale: number` 或 `scale: `[模板](../../docs/concepts/template)，定义每次放大或缩小图片的百分比大小，正值为放大，负值为缩小，默认 50 | 调整图片比例，将图片等比例放大或缩小 |

### preview

预览图片，可以通过配置`originalSrc`来指定预览的原图地址。

```schema: scope="body"
{
    "type": "page",
    "body": {
        "type": "container",
        "body": [
            {
                "type": "container",
                "body": [
                    {
                        "type": "image",
                        "className": "mb-1",
                        "src": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,w_216,l_1,f_jpg,q_80",
                        "originalSrc": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg",
                        "id": "previewImage"
                    }
                ]
            },
            {
                "type": "action",
                "label": "预览图片",
                "onEvent": {
                    "click": {
                        "actions": [
                            {
                                "actionType": "preview",
                                "componentId": "previewImage"
                            }
                        ]
                    }
                }
            }
        ]
    }
}
```

### zoom

调整图片比例，将图片等比例放大或缩小。可以通过配置图片的`maxScale`和`minScale`来限制调整的比例。

```
/* Detailed source-code truncated for AI context efficiency. */
```

---

### Zh CN Components Images (`docs/zh-CN/components/images.md`)

---
title: Images 图片集
description:
type: 0
group: ⚙ 组件
menuName: Images 图片集合
icon:
order: 53
---

图片集展示，不支持配置初始化接口初始化数据域，所以需要搭配类似像`Service`、`Form`或`CRUD`
这样的，具有配置接口初始化数据域功能的组件，或者手动进行数据域初始化，然后通过`source`属性，获取数据链中的数据，完成数据展示。

## 基本用法

通过 source 关联上下文数据，或者通过 name 关联。

```schema
{
    "type": "page",
    "data": {
        "imageList": [
            "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,w_216,l_1,f_jpg,q_80",
            "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692942/d8e4992057f9.jpeg@s_0,w_216,l_1,f_jpg,q_80",
            "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693148/1314a2a3d3f6.jpeg@s_0,w_216,l_1,f_jpg,q_80",
            "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693379/8f2e79f82be0.jpeg@s_0,w_216,l_1,f_jpg,q_80",
            "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693566/552b175ef11d.jpeg@s_0,w_216,l_1,f_jpg,q_80"
        ]
    },
    "body": [
        {
            "type": "images",
            "source": "${imageList}"
        },
        {
            "type": "divider"
        },
        {
            "type": "images",
            "name": "imageList"
        }
    ]
}
```

也可以静态展示，即不关联数据固定显示。

```schema
{
    "type": "page",
    "body": {
        "type": "images",
        "options": [
            "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,w_216,l_1,f_jpg,q_80",
            "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692942/d8e4992057f9.jpeg@s_0,w_216,l_1,f_jpg,q_80",
            "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693148/1314a2a3d3f6.jpeg@s_0,w_216,l_1,f_jpg,q_80",
            "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693379/8f2e79f82be0.jpeg@s_0,w_216,l_1,f_jpg,q_80",
            "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693566/552b175ef11d.jpeg@s_0,w_216,l_1,f_jpg,q_80"
        ]
    }
}
```

## 展示模式

通过配置 `displayMode` 可以设置图片集的展示模式,支持以下两种模式:

- `thumb`: 缩略图模式(默认),将图片以缩略图网格的形式展示
- `full`: 大图模式,以幻灯片形式展示单张大图,可左右滑动切换

在大图模式下,可以通过`fullThumbMode`属性来控制图片的缩放模式:

- `cover`: 保持图片比例,填充整个容器,可能会裁剪部分图片(默认)
- `contain`: 保持图片比例,确保图片完整显示在容器内

```schema
{
    "type": "page",
    "data": {
        "images": [
            {
                "image": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg",
                "title": "图片1"
            },
            {
                "image": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692942/d8e4992057f9.jpeg",
                "title": "图片2"
            },
            {
                "image": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693148/1314a2a3d3f6.jpeg",
                "title": "图片3"
            }
        ]
    },
    "body": [
        {
            "type": "images",
            "source": "${images}",
            "displayMode": "full",
            "fullThumbMode": "cover"
        }
    ]
}
```

## 图集排版方式

图集排列方式，通过 sortType 字段调整布局方式。四部分分别是上右下左方向顺时针排列，最小单位为 s，m 是 s 的 2 倍，l 是 m 的 2 倍。
`'sm-ss-sss-m'| 'sss-ss-ms-m'| 'sms-ss-sms-m' | 'sm-ss-sss-ss' | 'ms-ss-sss-ss'| 'sss-ss-sm-ss' | 'mss-ss-ssm-ss' | 'sss-ss-mm-ss';`
可以通过改变 width 和 height 来调整图片大小。默认宽度是 800，高度是 450。

### 主辅并排式

`sortType: 'sm-ss-sss-m'`

```schema: scope="body"
{
  "type": "page",
  "body": [
    {
      "type": "images",
      "sortType": "sm-ss-sss-m",
      "width":"200",
      "height":"112.5",
      "thumbMode": "cover",
      "value":[
        {
          "image": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,h_520,l_1,f_jpg,q_80",
          "title": "图片描述"
        },
        {
          "image": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692942/d8e4992057f9.jpeg@s_0,w_552,l_1,f_jpg,q_80",
          "title": "图片描述"
        },
        {
          "image": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693148/1314a2a3d3f6.jpeg@s_0,h_250,l_1,f_jpg,q_80",
          "title": "图片描述"
        },
        {
          "image": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693566/552b175ef11d.jpeg@s_0,h_250,l_1,f_jpg,q_80",
          "title": "图片描述"
        }
      ]
    },
  ]
}
```

### 上下分层式

`sortType: 'sss-ss-ms-m'`

```schema
{
  "type": "page",
  "body": [
    {
      "type": "images",
      "sortType": "sss-ss-ms-m",
      "thumbMode": "cover",
      "width":"200",
      "height":"112.5",
      "value":[
        {
          "image": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,h_520,l_1,f_jpg,q_80",
          "title": "图片描述"
        },
        {
          "image": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692942/d8e4992057f9.jpeg@s_0,w_250,l_1,f_jpg,q_80",
          "title": "图片描述"
        },
        {
          "image": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693148/1314a2a3d3f6.jpeg@s_0,w_250,l_1,f_jpg,q_80",
          "title": "图片描述"
        },
        {
          "image": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693566/552b175ef11d.jpeg@s_0,w_520,l_1,f_jpg,q_80",
          "title": "图片描述"
        }
      ]
    },
  ]
}
```

### 侧边栏嵌入式

`sortType: 'sms-ss-sms-m'`

```schema
{
  "type": "page",
  "body": [
    {
      "type": "images",
      "sortType": "sms-ss-sms-m",
      "thumbMode": "cover",
      "width":"200",
      "height":"112.5",
      "value":[
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,h_520,l_1,f_jpg,q_80",
          title: "图片描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692942/d8e4992057f9.jpeg@s_0,w_520,l_1,f_jpg,q_80",
          title: "图片描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693148/1314a2a3d3f6.jpeg@s_0,w_250,l_1,f_jpg,q_80",
          title: "图片描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693566/552b175ef11d.jpeg@s_0,w_520,l_1,f_jpg,q_80",
          title: "图片描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692942/d8e4992057f9.jpeg@s_0,w_250,l_1,f_jpg,q_80",
          title: "图片描述"
        }
      ],
    },
  ]
}
```

### 黄金比例分割式

`sortType: 'sm-ss-sss-ss'`

```schema
{
  "type": "page",
  "body": [
    {
      "type": "images",
      "sortType": "sm-ss-sss-ss",
      "thumbMode": "cover",
      "width":"200",
      "height":"112.5",
      "value":[
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,w_250,l_1,f_jpg,q_80",
          title: "图片描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692942/d8e4992057f9.jpeg@s_0,w_520,l_1,f_jpg,q_80",
          title: "图片描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693148/1314a2a3d3f6.jpeg@s_0,w_250,l_1,f_jpg,q_80",
          title: "图片描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693566/552b175ef11d.jpeg@s_0,w_250,l_1,f_jpg,q_80",
          title: "图片描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692942/d8e4992057f9.jpeg@s_0,w_250,l_1,f_jpg,q_80",
          title: "图片描述"
        }
      ]
    },
  ]
}
```

### 动态不对称式

`sortType: 'ms-ss-sss-ss'`

```schema
{
  "type": "page",
  "body": [
    {
      "type": "images",
      "sortType": "ms-ss-sss-ss",
      "thumbMode": "cover",
      "width":"200",
      "height":"112.5",
      "value":[
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,w_520,l_1,f_jpg,q_80",
          title: "图片描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692942/d8e4992057f9.jpeg@s_0,w_250,l_1,f_jpg,q_80",
          title: "图片描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693148/1314a2a3d3f6.jpeg@s_0,w_250,l_1,f_jpg,q_80",
          title: "图片描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693566/552b175ef11d.jpeg@s_0,w_250,l_1,f_jpg,q_80",
          title: "图片描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692942/d8e4992057f9.jpeg@s_0,w_250,l_1,f_jpg,q_80",
          title: "图片描述"
        }
      ]
    },
  ]
}
```

### 焦点引导式

`sortType: 'sss-ss-sm-ss'`

```schema
{
  "type": "page",
  "body": [
    {
      "type": "images",
      "sortType": "sss-ss-sm-ss",
      "thumbMode": "cover",
      "width":"200",
      "height":"112.5",
      "value":[
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,w_250,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692942/d8e4992057f9.jpeg@s_0,w_250,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693148/1314a2a3d3f6.jpeg@s_0,w_250,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693566/552b175ef11d.jpeg@s_0,w_520,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692942/d8e4992057f9.jpeg@s_0,w_250,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        }
      ]
    },
  ]
}
```

### 模块化组合式

`sortType: 'mss-ss-ssm-ss'`

```schema
{
  "type": "page",
  "body": [
    {
      "type": "images",
      "sortType": "mss-ss-ssm-ss",
      "thumbMode": "cover",
      "width":"200",
      "height":"112.5",
      "value":[
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,w_520,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692942/d8e4992057f9.jpeg@s_0,w_250,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693148/1314a2a3d3f6.jpeg@s_0,w_250,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693566/552b175ef11d.jpeg@s_0,w_520,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692942/d8e4992057f9.jpeg@s_0,w_250,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692942/d8e4992057f9.jpeg@s_0,w_250,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        }
      ]
    },
  ]
}
```

### 阶梯错落式

`sortType: 'sss-ss-mm-ss'`

```schema
{
  "type": "page",
  "body": [
    {
      "type": "images",
      "sortType": "sss-ss-mm-ss",
      "thumbMode": "cover",
      "width":"200",
      "height":"112.5",
      "value":[
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,w_250,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692942/d8e4992057f9.jpeg@s_0,w_250,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693148/1314a2a3d3f6.jpeg@s_0,w_250,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693566/552b175ef11d.jpeg@s_0,w_520,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692942/d8e4992057f9.jpeg@s_0,w_520,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
      ]
    },
  ]
}
```

### 网格式

`sortType: 'even-${number}-${number}'` 其中 number 可以是任意正整数

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 文字展示效果

在图集组件中，通过配置 `hoverMode`字段，来控制鼠标移入图片时，图片蒙层及文字效果。通过 `fontStyle`字段控制文字 css 样式

### 浮层滑动

`"hoverMode": "hover-slide"`

```schema
{
  "type": "page",
  "body": {
    "type": "container",
    "style":{
        width: "400px",
        height: "260px"
    },
    "body": {
      "type": "images",
      "hoverMode": "hover-slide",
      "sortType": "sm-ss-sss-m",
      "thumbMode": "cover",
      "width":"400",
      "height":"250",
      "value": [
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,h_250,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692942/d8e4992057f9.jpeg@s_0,w_270,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693148/1314a2a3d3f6.jpeg@s_0,w_250,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693566/552b175ef11d.jpeg@s_0,w_240,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
      ],
    },
  },
}
```

### 上拉

`"hoverMode": "pull-top"`

```schema
{
  "type": "page",
  "body": {
    "type": "container",
    "style":{
        width: "400px",
        height: "260px"
    },
    "body": {
      "type": "images",
      "hoverMode": "pull-top",
      "sortType": "sm-ss-sss-m",
      "thumbMode": "cover",
      "width":"400",
      "height":"250",
      "value":  [
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,h_250,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692942/d8e4992057f9.jpeg@s_0,w_270,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693148/1314a2a3d3f6.jpeg@s_0,w_250,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693566/552b175ef11d.jpeg@s_0,w_240,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
      ],
    },
  },
}
```

### 缩小居中

`"hoverMode": "scale-center"`

```schema
{
  "type": "page",
  "body": {
    "type": "container",
    "style":{
        width: "400px",
        height: "260px"
    },
    "body": {
      "type": "images",
      "hoverMode": "scale-center",
      "sortType": "sm-ss-sss-m",
      "thumbMode": "cover",
      "width":"400",
      "height":"250",
      "value": [
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,h_250,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692942/d8e4992057f9.jpeg@s_0,w_270,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693148/1314a2a3d3f6.jpeg@s_0,w_250,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693566/552b175ef11d.jpeg@s_0,w_240,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
      ],
    },
  },
}
```

### 缩小居上

`"hoverMode": "scale-top"`

```schema
{
  "type": "page",
  "body": {
    "type": "container",
    "style":{
        width: "400px",
        height: "260px"
    },
    "body": {
      "type": "images",
      "hoverMode": "scale-top",
      "sortType": "sm-ss-sss-m",
      "thumbMode": "cover",
      "width":"400",
      "height":"250",
      "value":  [
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,h_250,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692942/d8e4992057f9.jpeg@s_0,w_270,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693148/1314a2a3d3f6.jpeg@s_0,w_250,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693566/552b175ef11d.jpeg@s_0,w_240,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
      ],
    },
  },
}
```

### 文字效果一

`"hoverMode": "text-style-1"`

```schema
{
  "type": "page",
  "body": {
    "type": "container",
    "style":{
        width: "400px",
        height: "260px"
    },
    "body": {
      "type": "images",
      "hoverMode": "text-style-1",
      "sortType": "sm-ss-sss-m",
      "thumbMode": "cover",
      "width":"400",
      "height":"250",
      "value":  [
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,h_250,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692942/d8e4992057f9.jpeg@s_0,w_270,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693148/1314a2a3d3f6.jpeg@s_0,w_250,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693566/552b175ef11d.jpeg@s_0,w_240,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
      ],
    },
  },
}
```

### 文字效果二

`"hoverMode": "text-style-2"`

```schema
{
  "type": "page",
  "body": {
    "type": "container",
    "style":{
        width: "400px",
        height: "260px"
    },
    "body": {
      "type": "images",
      "hoverMode": "text-style-2",
      "sortType": "sm-ss-sss-m",
      "thumbMode": "cover",
      "width":"400",
      "height":"250",
      "value":  [
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,h_250,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692942/d8e4992057f9.jpeg@s_0,w_270,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693148/1314a2a3d3f6.jpeg@s_0,w_250,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693566/552b175ef11d.jpeg@s_0,w_240,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
      ],
    },
  },
}
```

### 文字效果三

`"hoverMode": "text-style-3"`

```schema
{
  "type": "page",
  "body": {
    "type": "container",
    "style":{
        width: "400px",
        height: "260px"
    },
    "body": {
      "type": "images",
      "hoverMode": "text-style-3",
      "sortType": "sm-ss-sss-m",
      "thumbMode": "cover",
      "width":"400",
      "height":"250",
      "value":  [
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,h_250,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692942/d8e4992057f9.jpeg@s_0,w_270,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693148/1314a2a3d3f6.jpeg@s_0,w_250,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693566/552b175ef11d.jpeg@s_0,w_240,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
      ],
    },
  },
}
```

### 文字效果四

`"hoverMode": "text-style-4"`

```schema
{
  "type": "page",
  "body": {
    "type": "container",
    "style":{
        width: "400px",
        height: "260px"
    },
    "body": {
      "type": "images",
      "hoverMode": "text-style-4",
      "sortType": "sm-ss-sss-m",
      "thumbMode": "cover",
      "width":"400",
      "height":"250",
      "value": [
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,h_250,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692942/d8e4992057f9.jpeg@s_0,w_270,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693148/1314a2a3d3f6.jpeg@s_0,w_250,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693566/552b175ef11d.jpeg@s_0,w_240,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
      ],
    },
  },
}
```

### 文字效果五

`"hoverMode": "text-style-5"`

```schema
{
  "type": "page",
  "body": {
    "type": "container",
    "style":{
        width: "400px",
        height: "260px"
    },
    "body": {
      "type": "images",
      "hoverMode": "text-style-5",
      "sortType": "sm-ss-sss-m",
      "thumbMode": "cover",
      "width":"400",
      "height":"250",
      "value": [
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,h_250,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692942/d8e4992057f9.jpeg@s_0,w_270,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693148/1314a2a3d3f6.jpeg@s_0,w_250,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693566/552b175ef11d.jpeg@s_0,w_240,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
      ],
    },
  },
}
```

### 文字效果六

`"hoverMode": "text-style-6"`

```schema
{
  "type": "page",
  "body": {
    "type": "container",
    "style":{
        width: "400px",
        height: "260px"
    },
    "body": {
      "type": "images",
      "hoverMode": "text-style-6",
      "sortType": "sm-ss-sss-m",
      "thumbMode": "cover",
      "width":"400",
      "height":"250",
      "value": [
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,h_250,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692942/d8e4992057f9.jpeg@s_0,w_270,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693148/1314a2a3d3f6.jpeg@s_0,w_250,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693566/552b175ef11d.jpeg@s_0,w_240,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
      ],
    },
  },
}
```

### 文字效果七

`"hoverMode": "text-style-7"`

```schema
{
  "type": "page",
  "body": {
    "type": "container",
    "style":{
        width: "400px",
        height: "260px"
    },
    "body": {
      "type": "images",
      "hoverMode": "text-style-7",
      "sortType": "sm-ss-sss-m",
      "thumbMode": "cover",
      "width":"400",
      "height":"250",
      "value": [
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,h_250,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692942/d8e4992057f9.jpeg@s_0,w_270,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693148/1314a2a3d3f6.jpeg@s_0,w_250,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
        {
          image: "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693566/552b175ef11d.jpeg@s_0,w_240,l_1,f_jpg,q_80",
          title: "图片描述",
          description: "这是一段描述"
        },
      ],
    },
  },
}
```

## 值格式

除了支持纯文本数组以外，也支持对象数组，如：

```ts
Array<{
  image: string; // 小图，预览图
  src?: string; // 原图
  title?: string; // 标题
  description?: string; // 描述
  [propName: string]: any; // 还可以有其他数据
}>;
```

### 配置预览图地址

需要设置对象中预览图地址的`key`值为`image`

```schema
{
    "type": "page",
    "data": {
        "images": [
            {
                "image": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,w_216,l_1,f_jpg,q_80",
                "a": "aaa1",
                "b": "bbb1"
            },
            {
                "image": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692942/d8e4992057f9.jpeg@s_0,w_216,l_1,f_jpg,q_80",
                "a": "aaa2",
                "b": "bbb2"
            },
            {
                "image": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693148/1314a2a3d3f6.jpeg@s_0,w_216,l_1,f_jpg,q_80",
                "a": "aaa3",
                "b": "bbb3"
            },
            {
                "image": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693379/8f2e79f82be0.jpeg@s_0,w_216,l_1,f_jpg,q_80",
                "a": "aaa4",
                "b": "bbb4"
            },
            {
                "image": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693566/552b175ef11d.jpeg@s_0,w_216,l_1,f_jpg,q_80",
                "a": "aaa5",
                "b": "bbb5"
            }
        ]
    },
    "body": {
        "type": "images",
        "source": "${images}"
    }
}
```

如果`key`值不是`image`，也可以在 **images 组件** 上，通过配置`src`，使用数据映射，来获取图片地址

```schema
{
    "type": "page",
    "data": {
        "images": [
            {
                "img": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,w_216,l_1,f_jpg,q_80",
                "a": "aaa1",
                "b": "bbb1"
            },
            {
                "img": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692942/d8e4992057f9.jpeg@s_0,w_216,l_1,f_jpg,q_80",
                "a": "aaa2",
                "b": "bbb2"
            },
            {
                "img": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693148/1314a2a3d3f6.jpeg@s_0,w_216,l_1,f_jpg,q_80",
                "a": "aaa3",
                "b": "bbb3"
            },
            {
                "img": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693379/8f2e79f82be0.jpeg@s_0,w_216,l_1,f_jpg,q_80",
                "a": "aaa4",
                "b": "bbb4"
            },
            {
                "img": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693566/552b175ef11d.jpeg@s_0,w_216,l_1,f_jpg,q_80",
                "a": "aaa5",
                "b": "bbb5"
            }
        ]
    },
    "body": {
        "type": "images",
        "source": "${images}",
        "src": "${img}"
    }
}
```

### 配置原图地址

需要设置对象中原图地址的`key`值为`src`

```
/* Detailed source-code truncated for AI context efficiency. */
```

如果原图数据的`key`值不是`src`，也可以在 **images 组件** 上，通过配置`originalSrc`，使用数据映射，来获取原图片地址

```
/* Detailed source-code truncated for AI context efficiency. */
```

### 配置标题和说明

设置对象中标题的`key`值为`title`，说明的`key`为`description`或`caption`。

```schema
{
    "type": "page",
    "data": {
        "images": [
            {
                "image": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,w_216,l_1,f_jpg,q_80",
                "title": "图片1",
                "description": "图片1的描述"
            },
            {
                "image": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692942/d8e4992057f9.jpeg@s_0,w_216,l_1,f_jpg,q_80",
                "title": "图片2",
                "description": "图片2的描述"
            },
            {
                "image": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693148/1314a2a3d3f6.jpeg@s_0,w_216,l_1,f_jpg,q_80",
                "title": "图片3",
                "description": "图片3的描述"
            },
            {
                "image": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693379/8f2e79f82be0.jpeg@s_0,w_216,l_1,f_jpg,q_80",
                "title": "图片4",
                "description": "图片4的描述"
            },
            {
                "image": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693566/552b175ef11d.jpeg@s_0,w_216,l_1,f_jpg,q_80",
                "title": "图片5",
                "description": "图片5的描述"
            }
        ]
    },
    "body": {
        "type": "images",
        "source": "${images}"
    }
}
```

## 显示比例和缩略图模式

比如这个例子配置成 16:9 的比率展示缩略图，并裁剪部分去掉空白。

```schema
{
    "type": "page",
    "body": {
        "type": "images",
        "thumbRatio": "16:9",
        "thumbMode": "cover",
        "options": [
            "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,w_216,l_1,f_jpg,q_80",
            "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692942/d8e4992057f9.jpeg@s_0,w_216,l_1,f_jpg,q_80",
            "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693148/1314a2a3d3f6.jpeg@s_0,w_216,l_1,f_jpg,q_80",
            "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693379/8f2e79f82be0.jpeg@s_0,w_216,l_1,f_jpg,q_80",
            "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693566/552b175ef11d.jpeg@s_0,w_216,l_1,f_jpg,q_80"
        ]
    }
}
```

## 配置放大预览

在 **images 组件** 上，配置`enlargeAble`，支持放大预览

```
/* Detailed source-code truncated for AI context efficiency. */
```

图片组件配置`"enlargeWithGallary": false`可以关闭放大模式下图片集列表的展示，表格中亦是如此。

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 用作 Field 时

当用在 Table 的列配置 Column、List 的内容、Card 卡片的内容和表单的 Static-XXX 中时，可以设置`name`属性，映射同名变量

### Table 中的列类型

```
/* Detailed source-code truncated for AI context efficiency. */
```

Table 中图片组件配置`"enlargeWithGallary": true`可以在放大模式下预览列表中的所有图片集。

```
/* Detailed source-code truncated for AI context efficiency. */
```

Table 中图片组件配置`"enlargeWithGallary": false`可以关闭放大模式下图片集列表的展示。

```
/* Detailed source-code truncated for AI context efficiency. */
```

List 的内容、Card 卡片的内容配置同上。

### Form 中关联数据静态展示

```schema: scope="body"
{
    "type": "form",
    "data": {
        "images": [
            "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,w_216,l_1,f_jpg,q_80",
            "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692942/d8e4992057f9.jpeg@s_0,w_216,l_1,f_jpg,q_80",
            "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693148/1314a2a3d3f6.jpeg@s_0,w_216,l_1,f_jpg,q_80",
            "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693379/8f2e79f82be0.jpeg@s_0,w_216,l_1,f_jpg,q_80",
            "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693566/552b175ef11d.jpeg@s_0,w_216,l_1,f_jpg,q_80"
        ]
    },
    "body": [
        {
            "type": "static-images",
            "name": "images",
            "label": "图片集"
        }
    ]
}
```

## 工具栏

> 2.2.0 及以上版本

配置`"showToolbar": true`使图片在放大模式下开启图片工具栏。配置`"toolbarActions"`
属性可以自定义工具栏的展示方式，具体配置参考[ImageAction](./image#imageaction)

```schema
{
    "type": "page",
    "data": {
        "images": [
            {
                "image": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,w_216,l_1,f_jpg,q_80",
                "a": "aaa1",
                "b": "bbb1"
            },
            {
                "image": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692942/d8e4992057f9.jpeg@s_0,w_216,l_1,f_jpg,q_80",
                "a": "aaa2",
                "b": "bbb2"
            },
            {
                "image": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693148/1314a2a3d3f6.jpeg@s_0,w_216,l_1,f_jpg,q_80",
                "a": "aaa3",
                "b": "bbb3"
            },
            {
                "image": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693379/8f2e79f82be0.jpeg@s_0,w_216,l_1,f_jpg,q_80",
                "a": "aaa4",
                "b": "bbb4"
            },
            {
                "image": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693566/552b175ef11d.jpeg@s_0,w_216,l_1,f_jpg,q_80",
                "a": "aaa5",
                "b": "bbb5"
            }
        ]
    },
    "body": {
        "type": "images",
        "source": "${images}",
        "enlargeAble": true,
        "showToolbar": true
    }
}
```

## 属性表

| 属性名                | 类型                                                                                                                                                        | 默认值                    | 说明                                                                         | 版本      |
|--------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------|----------------------------------------------------------------------------|---------|
| type               | `string`                                                                                                                                                  | `images`               | 如果在 Table、Card 和 List 中，为`"images"`；在 Form 中用作静态展示，为`"static-images"`      |
| className          | `string`                                                                                                                                                  |                        | 外层 CSS 类名                                                                  |
| defaultImage       | `string`                                                                                                                                                  |                        | 默认展示图片                                                                     |
| value              | `string`或`Array<string>`或`Array<object>`                                                                                                                  |                        | 图片数组                                                                       |
| source             | `string`                                                                                                                                                  |                        | 数据源                                                                        |
| delimiter          | `string`                                                                                                                                                  | `,`                    | 分隔符，当 value 为字符串时，用该值进行分隔拆分                                                |
| src                | `string`                                                                                                                                                  |                        | 预览图地址，支持数据映射获取对象中图片变量                                                      |
| originalSrc        | `string`                                                                                                                                                  |                        | 原图地址，支持数据映射获取对象中图片变量                                                       |
| enlargeAble        | `boolean`                                                                                                                                                 |                        | 支持放大预览                                                                     |
| enlargeWithGallary | `string`                                                                                                                                                  |                        | 默认在放大功能展示图片集的所有图片信息；表格中使用时，设置为`true`将展示所有行的图片信息；设置为`false`将关闭放大模式下图片集列表的展示 |
| thumbMode          | `string`                                                                                                                                                  | `contain`              | 预览图模式，可选：`'w-full'`, `'h-full'`, `'contain'`, `'cover'`                    |
| thumbRatio         | `string`                                                                                                                                                  | `1:1`                  | 预览图比例，可选：`'1:1'`, `'4:3'`, `'16:9'`                                        |
| showToolbar        | `boolean`                                                                                                                                                 | `false`                | 放大模式下是否展示图片的工具栏                                                            | `2.2.0` |
| toolbarActions     | `ImageAction[]`                                                                                                                                           |                        | 图片工具栏，支持旋转，缩放，默认操作全部开启                                                     | `2.2.0` |
| sortType           | `'sm-ss-sss-m'｜ 'sss-ss-ms-m'｜'sms-ss-sms-m'｜'sm-ss-sss-ss'｜ 'ms-ss-sss-ss'｜ 'sss-ss-sm-ss'｜ 'mss-ss-ssm-ss'｜ 'sss-ss-mm-ss'｜ 'even-${number}-${number}'` |                        | 图集排列方式                                                                     |         |
| hoverMode          | `hover-slide｜pull-top｜scale-center｜scale-top｜text-style-1｜text-style-2｜text-style-3｜text-style-4｜text-style-5｜text-style-6｜text-style-7 `                 |                        | 鼠标悬浮时的展示状态                                                                 |         |
| fontStyle          | `{"fontSize":"string", "color": "string", "fontFamily": "string"...}`                                                                                     | `{"fontSize": "15px"}` | 字体样式                                                                       |         |
| maskColor          | `string`                                                                                                                                                  |                        | 遮罩层颜色，可以是rgba值，可以是图片                                                       |         |
| displayMode        | `'thumb' \| 'full'`                                                                                                                                       | `'thumb'`              | 展示模式,支持缩略图模式（thumb）和大图模式（full）                                             |
| fullThumbMode      | `'cover' \| 'contain'`                                                                                                                                    | `'cover'`              | 大图模式下的图片缩放模式                                                               |

---

### Zh CN Components Json (`docs/zh-CN/components/json.md`)

---
title: Json
description:
type: 0
group: ⚙ 组件
menuName: Json
icon:
order: 54
---

JSON 展示组件

## 基本用法

可以配置 `value` 展示 `json` 格式数据

```schema
{
    "type": "page",
    "body": {
        "type": "json",
        "value": {
            "a": "a",
            "b": "b",
            "c": {
                "d": "d"
            }
        }
    }
}
```

## 获取数据链值

也可以通过配置 `source` 获取数据链中的值

```schema
{
    "type": "page",
    "data":{
        "json":{
            "a": "a",
            "b": {
                "c": "c"
            }
        }
    },
    "body": {
        "type": "json",
        "source": "${json}"
    }
}
```

## 用作 Field 时

当用在 Table 的列配置 Column、List 的内容、Card 卡片的内容和表单的 Static-XXX 中时，可以设置`name`属性，映射同名变量

### Table 中的列类型

```schema: scope="body"
{
    "type": "table",
    "data": {
        "items": [
            {
                "id": "1",
                "json": {
                    "a": "a1",
                    "b": {
                        "c": "c1"
                    }
                }
            },
            {
                "id": "2",
                "json": {
                    "a": "a2",
                    "b": {
                        "c": "c2"
                    }
                }
            },
            {
                "id": "3",
                "json": {
                    "a": "a3",
                    "b": {
                        "c": "c3"
                    }
                }
            }
        ]
    },
    "columns": [
        {
            "name": "id",
            "label": "Id"
        },

        {
            "name": "json",
            "label": "颜色",
            "type": "json"
        }
    ]
}
```

List 的内容、Card 卡片的内容配置同上

### Form 中静态展示

```schema: scope="body"
{
    "type": "form",
    "data": {
        "json": {
            "a": "a",
            "b": {
                "c": "c"
            }
        }
    },
    "body": [
        {
            "type": "control",
            "name": "json",
            "label": "Json",
            "body": {
                "type": "json"
            }
        }
    ]
}
```

## 主题

可配置`jsonTheme`，指定显示主题，可选`twilight`和`eighties`，默认为`twilight`。

```schema: scope="body"
[
{
    "type": "json",
    "value": {
        "a": "a",
        "b": "b",
        "c": {
            "d": "d"
        }
    }
},
{
    "type": "divider"
},
{
    "type": "json",
    "jsonTheme": "eighties",
    "value": {
        "a": "a",
        "b": "b",
        "c": {
            "d": "d"
        }
    }
}
]
```

## 配置默认展开层级

```schema
{
    "type": "page",
    "body": {
        "type": "json",
        "levelExpand": 0,
        "value": {
            "a": "a",
            "b": "b",
            "c": {
                "d": "d"
            }
        }
    }
}
```

如上，`levelExpand`配置为`0`，则默认不展开。

## 开启 json 修改

> since 1.2.3

可配置`mutable` 为 true，展示 json 的同时支持修改。记得配置 name 属性。

```schema: scope="body"
[
{
    "type": "json",
    "name": "json",
    "mutable": true,
    "value": {
        "a": "a",
        "b": "b",
        "c": {
            "d": "d"
        }
    }
}
]
```

## 显示数据类型显示

还可以使用 `displayDataTypes` 开启数据类型显示

```schema
{
    "type": "page",
    "body": {
        "type": "json",
        "displayDataTypes":  true,
        "value": {
            "a": 1,
            "b": "b",
            "c": {
                "d": "d"
            }
        }
    }
}
```

## 文本过长自动处理

> 2.0.0 及以上版本

设置`ellipsisThreshold`可以设置字符串的最大展示长度，点击字符串可以切换全量/部分展示方式，默认展示全量字符串。

```schema
{
    "type": "page",
    "body": {
        "type": "json",
        "ellipsisThreshold": 80,
        "value": {
            "text": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",
        }
    }
}
```

## 属性表

| 属性名            | 类型              | 默认值     | 说明                                                                                 |
| ----------------- | ----------------- | ---------- | ------------------------------------------------------------------------------------ |
| type              | `string`          |            | 如果在 Table、Card 和 List 中，为`"json"`；在 Form 中用作静态展示，为`"static-json"` |
| className         | `string`          |            | 外层 CSS 类名                                                                        |
| value             | `object`/`string` |            | json 值，如果是 string 会自动 parse                                                  |
| source            | `string`          | `''`       | 通过数据映射获取数据链中的值                                                         |
| placeholder       | `string`          | `-`        | 占位文本                                                                             |
| levelExpand       | `number`          | `1`        | 默认展开的层级                                                                       |
| jsonTheme         | `string`          | `twilight` | 主题，可选`twilight`和`eighties`                                                     |
| mutable           | `boolean`         | `false`    | 是否可修改                                                                           |
| displayDataTypes  | `boolean`         | `false`    | 是否显示数据类型                                                                     |
| ellipsisThreshold | `number`          | `false`    | 设置字符串的最大展示长度，点击字符串可以切换全量/部分展示方式，默认展示全量字符串    |

---

### Zh CN Components Link (`docs/zh-CN/components/link.md`)

---
title: Link 链接
description:
type: 0
group: ⚙ 组件
menuName: Link
icon:
order: 55
---

## 基本用法

```schema
{
    "type": "page",
    "body": {
        "type": "link",
        "href": "https://www.baidu.com",
        "body": "百度一下，你就知道"
    }
}
```

## 新标签页打开

```schema
{
    "type": "page",
    "body": {
        "type": "link",
        "href": "https://www.baidu.com",
        "body": "百度一下，你就知道",
        "blank": true
    }
}
```

## 禁用超链接

```schema
{
    "type": "page",
    "body": {
        "type": "link",
        "href": "https://www.baidu.com",
        "body": "百度一下，你就知道",
        "blank": true,
        "disabled": true
    }
}
```

## 添加图标

```schema
{
    "type": "page",
    "body": {
        "type": "link",
        "href": "https://www.baidu.com",
        "body": "百度一下，你就知道",
        "blank": true,
        "icon": "fa fa-search"
    }
}
```

## 属性表

| 属性名     | 类型      | 默认值 | 说明                                                                                 |
| ---------- | --------- | ------ | ------------------------------------------------------------------------------------ |
| type       | `string`  |        | 如果在 Table、Card 和 List 中，为`"link"`；在 Form 中用作静态展示，为`"static-link"` |
| body       | `string`  |        | 标签内文本                                                                           |
| href       | `string`  |        | 链接地址                                                                             |
| blank      | `boolean` |        | 是否在新标签页打开                                                                   |
| htmlTarget | `string`  |        | a 标签的 target，优先于 blank 属性                                                   |
| title      | `string`  |        | a 标签的 title                                                                       |
| disabled   | `boolean` |        | 禁用超链接                                                                           |
| icon       | `string`  |        | 超链接图标，以加强显示                                                               |
| rightIcon  | `string`  |        | 右侧图标                                                                             |

---

### Zh CN Components List (`docs/zh-CN/components/list.md`)

---
title: List 列表
description:
type: 0
group: ⚙ 组件
menuName: List
icon:
order: 56
---

列表展示，不支持配置初始化接口初始化数据域，所以需要搭配类似像`Service`这样的，具有配置接口初始化数据域功能的组件，或者手动进行数据域初始化，然后通过`source`属性，获取数据链中的数据，完成数据展示。

## 基本用法

```schema: scope="body"
{
  "type": "service",
  "api": "/api/mock2/sample?perPage=5",
  "body": [
    {
      "type": "list",
      "source": "$rows",
      "listItem": {
        "body": [
          {
            "type": "hbox",
            "columns": [
              {
                "label": "Engine",
                "name": "engine"
              },

              {
                "name": "version",
                "label": "Version"
              }
            ]
          }
        ],
        "actions": [
          {
            "type": "button",
            "level": "link",
            "label": "查看详情",
            "actionType": "dialog",
            "dialog": {
              "title": "查看详情",
              "body": {
                "type": "form",
                "body": [
                  {
                    "label": "Engine",
                    "name": "engine",
                    "type": "static"
                  },
                  {
                    "name": "version",
                    "label": "Version",
                    "type": "static"
                  }
                ]
              }
            }
          }
        ]
      }
    }
  ]
}
```

## 选择模式

设置`"selectable": true`, 列表开启多选模式

```schema: scope="body"
{
  "type": "service",
  "api": "/api/mock2/sample?perPage=5",
  "body": [
    {
      "type": "list",
      "selectable": true,
      "source": "$rows",
      "listItem": {
        "body": [
          {
            "type": "hbox",
            "columns": [
              {
                "label": "Engine",
                "name": "engine"
              },

              {
                "name": "version",
                "label": "Version"
              }
            ]
          }
        ]
      }
    }
  ]
}
```

列表默认支持多选，设置`"multiple": false`开启单选模式

```schema: scope="body"
{
  "type": "service",
  "api": "/api/mock2/sample?perPage=5",
  "body": [
    {
      "type": "list",
      "selectable": true,
      "multiple": false,
      "source": "$rows",
      "listItem": {
        "body": [
          {
            "type": "hbox",
            "columns": [
              {
                "label": "Engine",
                "name": "engine"
              },

              {
                "name": "version",
                "label": "Version"
              }
            ]
          }
        ]
      }
    }
  ]
}
```

或者你也可以使用 CRUD 的 [list 模式](./crud#list-%E5%88%97%E8%A1%A8%E6%A8%A1%E5%BC%8F)

## 单行点击操作

> 1.4.0 及以上版本

配置 itemAction 可以实现点击某一行后进行操作，支持 [action](./action) 里的所有配置，比如弹框、刷新其它组件等。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/mock2/sample?perPage=5",
  "body": [
    {
      "type": "list",
      "source": "$rows",
      "itemAction": {
        "type": "button",
        "actionType": "dialog",
        "dialog": {
          "title": "详情",
          "body": "当前行的数据 browser: ${browser}, version: ${version}"
        }
      },
      "listItem": {
        "body": [
          {
            "type": "hbox",
            "columns": [
              {
                "label": "Engine",
                "name": "engine"
              },

              {
                "name": "version",
                "label": "Version"
              }
            ]
          }
        ],
        "actions": [
          {
            "type": "button",
            "level": "link",
            "label": "查看详情",
            "actionType": "dialog",
            "dialog": {
              "title": "查看详情",
              "body": {
                "type": "form",
                "body": [
                  {
                    "label": "Engine",
                    "name": "engine",
                    "type": "static"
                  },
                  {
                    "name": "version",
                    "label": "Version",
                    "type": "static"
                  }
                ]
              }
            }
          }
        ]
      }
    }
  ]
}
```

## 设置组件的 CSS 类

`className`属性会添加到组件外层 DOM 节点上，如果要在组件当前层级添加 CSS 类，请设置`innerClassName`属性

```schema: scope="body"
{
  "type": "service",
  "api": "/api/mock2/sample?perPage=5",
  "body": [
    {
      "type": "list",
      "source": "$rows",
      "listItem": {
        "body": {
          "type": "wrapper",
          "className": "border-4 border-solid border-primary",
          "innerClassName": "border-4 border-solid border-success",
          "body": [
            {
              "type": "tpl",
              "tpl": "Lorem Ipsum is simply dummy text of the printing and typesetting industry."
            }
          ]
        }
      }
    }
  ]
}
```

## 字母索引条

设置 `showIndexBar: true` 可以在列表右侧显示字母索引条，点击字母可以快速定位到以该字母开头的列表项。默认使用 `title` 字段作为索引依据，也可以通过 `indexField` 指定其他字段。

设置 `indexBarOffset` 可以设置字母索引条偏移量，用于设置点击索引条跳转时的滚动位置偏移。

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 属性表

| 属性名                   | 类型                                 | 默认值                | 说明                                                                         |
| ------------------------ | ------------------------------------ | --------------------- | ---------------------------------------------------------------------------- |
| type                     | `string`                             |                       | `"list"` 指定为列表展示。                                                    |
| title                    | `string`                             |                       | 标题                                                                         |
| source                   | `string`                             | `${items}`            | 数据源, 获取当前数据域变量，支持[数据映射](../../docs/concepts/data-mapping) |
| placeholder              | `string`                             | ‘暂无数据’            | 当没数据的时候的文字提示                                                     |
| selectable               | `boolean`                            | `false`               | 列表是否可选                                                                 |
| multiple                 | `boolean`                            | `true`                | 列表是否为多选                                                               |
| className                | `string`                             |                       | 外层 CSS 类名                                                                |
| headerClassName          | `string`                             | `amis-list-header`    | 顶部外层 CSS 类名                                                            |
| footerClassName          | `string`                             | `amis-list-footer`    | 底部外层 CSS 类名                                                            |
| listItem                 | `Array`                              |                       | 配置单条信息                                                                 |
| listItem.title           | [模板](../../docs/concepts/template) |                       | 标题                                                                         |
| listItem.titleClassName  | `string`                             | `h5`                  | 标题 CSS 类名                                                                |
| listItem.subTitle        | [模板](../../docs/concepts/template) |                       | 副标题                                                                       |
| listItem.avatar          | [模板](../../docs/concepts/template) |                       | 图片地址                                                                     |
| listItem.avatarClassName | `string`                             | `thumb-sm avatar m-r` | 图片 CSS 类名                                                                |
| listItem.desc            | [模板](../../docs/concepts/template) |                       | 描述                                                                         |
| listItem.body            | `ListBodyField[]`                    |                       | 内容容器，主要用来放置非表单项组件                                           |
| listItem.actions         | Array<[Action](./action)>            |                       | 按钮区域                                                                     |
| listItem.actionsPosition | 'left' or 'right'                    | 默认在右侧            | 按钮位置                                                                     |
| showIndexBar             | `boolean`                            | `false`               | 是否显示右侧字母索引条                                                       |
| indexField               | `string`                             | `'title'`             | 索引依据字段，默认使用 `title` 字段或列表项标题                              |
| indexBarOffset           | `number`                             | `0`                   | 索引条偏移量，用于设置点击索引条跳转时的滚动位置偏移                         |

### ListBodyField

```typescript
interface ListBodyField {
  /* 列标题 */
  label?: string;
  /* 外层DOM的CSS类名 */
  className?: string;
  /* label的CSS类名 */
  labelClassName?: string;
  /* 内层组件的CSS类名，className属性会添加到外层DOM，如果要在组件层级添加CSS类，请设置当前属性 */
  innerClassName?: string;
  /* 绑定字段名 */
  name?: string;
  /* 配置查看详情功能 */
  popOver?: SchemaPopOver;
  /* 配置快速编辑功能 */
  quickEdit?: SchemaQuickEdit;
  /* 配置点击复制功能 */
  copyable?: SchemaCopyable;
}
```

## 事件表

当前组件会对外派发以下事件，可以通过`onEvent`来监听这些事件，并通过`actions`来配置执行的动作，在`actions`中可以通过`${事件参数名}`或`${event.data.[事件参数名]}`来获取事件产生的数据，详细请查看[事件动作](../../docs/concepts/event-action)。

> `[name]`表示当前组件绑定的名称，即`name`属性，如果没有配置`name`属性，则通过`value`取值。

| 事件名称  | 事件参数      | 说明                                                                                                                         | 版本    |
| --------- | ------------- | ---------------------------------------------------------------------------------------------------------------------------- | ------- |
| itemClick | `item: IItem` | 单行被点击时触发，`IItem`为点击行的信息。注意`itemAction`和`onEvent`是互斥的，List 组件中的`onEvent`会覆盖`itemAction`的行为 | `2.4.0` |

**IItem**

| 属性名 | 类型                  | 默认值 | 说明                |
| ------ | --------------------- | ------ | ------------------- |
| data   | `Record<string, any>` |        | 当前行所在数据域    |
| index  | `number`              |        | 行索引值，从 0 开始 |

### itemClick

```schema: scope="body"
{
  "type": "service",
  "api": "/api/mock2/sample?perPage=5",
  "body": [
    {
      "type": "list",
      "source": "$rows",
      "listItem": {
        "body": [
          {
            "type": "hbox",
            "columns": [
              {
                "label": "Engine",
                "name": "engine"
              },
              {
                "name": "version",
                "label": "Version"
              }
            ]
          }
        ]
      },
      "onEvent": {
        "itemClick": {
          "actions": [
            {
              "actionType": "toast",
              "args": {
                "msgType": "info",
                "msg": "${event.data.item.index} ${event.data.item.data.engine}"
              }
            }
          ]
        }
      }
    }
  ]
}
```

## 动作表

> 6.4.0 或更高版本

当前组件对外暴露以下特性动作，其他组件可以通过指定`actionType: 动作名称`、`componentId: 该组件id`来触发这些动作，动作配置可以通过`args: {动作配置项名称: xxx}`来配置具体的参数，详细请查看[事件动作](../../docs/concepts/event-action#触发其他组件的动作)。

| 动作名称        | 动作配置                                                                                                                                | 说明                 |
| --------------- | --------------------------------------------------------------------------------------------------------------------------------------- | -------------------- |
| select          | `args.index` 可选，指定行数，支持表达式 <br /> `args.condition` 可选，通过表达式指定更新哪些行，支持条件组合 index`                     | 设置列表的选中项     |
| selectAll       | -                                                                                                                                       | 设置列表全部项选中   |
| clearAll        | -                                                                                                                                       | 清空列表所有选中项   |
| initDrag        | -                                                                                                                                       | 开启列表拖拽排序功能 |
| cancelDrag      | -                                                                                                                                       | 放弃列表拖拽排序功能 |
| setValue        | `args.value`: object <br />`args.index` 可选，指定行数，支持表达式 <br /> `args.condition` 可选，通过表达式指定更新哪些行，支持条件组合 | 更新列表记录         |
| submitQuickEdit |                                                                                                                                         | 快速编辑数据提交     |

### select

- `args.index` 可选，指定行数，支持表达式
- `args.condition` 可选，通过表达式指定更新哪些行，支持条件组合

```schema: scope="body"
[
    {
    "type": "button-toolbar",
    "className": "m-b",
    "buttons": [
    {
        "name": "trigger1",
        "id": "trigger1",
        "type": "action",
        "label": "选中前两个",
        "onEvent": {
        "click": {
            "actions": [
            {
                "actionType": "select",
                "componentId": "list-select",
                "args": {
                    "index": "0,1"
                }
            }
            ]
        }
        }
    }
    ]
},
{
    "type": "service",
    "api": "/api/mock2/sample?perPage=5",
    "body": [
    {
      "id": "list-select",
      "type": "list",
      "source": "$rows",
      "selectable": true,
      "multiple": true,
      "listItem": {
        "body": [
          {
            "type": "hbox",
            "columns": [
              {
                "label": "Engine",
                "name": "engine"
              },

              {
                "name": "version",
                "label": "Version"
              }
            ]
          }
        ]
      }
    }
  ]
}
]
```

### selectAll

```schema: scope="body"
[
    {
    "type": "button-toolbar",
    "className": "m-b",
    "buttons": [
    {
        "name": "trigger2",
        "id": "trigger2",
        "type": "action",
        "label": "设置列表全部项选中",
        "onEvent": {
        "click": {
            "actions": [
            {
                "actionType": "selectAll",
                "componentId": "list-select",
                "description": "点击设置指定列表全部内容选中"
            }
            ]
        }
        }
    }
    ]
},
{
    "type": "service",
    "api": "/api/mock2/sample?perPage=10",
    "body": [
    {
        "id": "list-select",
        "type": "list",
        "source": "$rows",
        "selectable": true,
        "multiple": true,
        "listItem": {
        "body": [
          {
            "type": "hbox",
            "columns": [
              {
                "label": "Engine",
                "name": "engine"
              },

              {
                "name": "version",
                "label": "Version"
              }
            ]
          }
        ]
      }
    }
    ]
}
]
```

### clearAll

```schema: scope="body"
[
    {
    "type": "button-toolbar",
    "className": "m-b",
    "buttons": [
    {
        "name": "trigger3",
        "id": "trigger3",
        "type": "action",
        "label": "清空列表全部选中项",
        "onEvent": {
        "click": {
            "actions": [
            {
                "actionType": "clearAll",
                "componentId": "list-select",
                "description": "点击设置指定列表全部选中项清空"
            }
            ]
        }
        }
    }
    ]
},
{
    "type": "service",
    "api": "/api/mock2/sample?perPage=10",
    "body": [
    {
        "id": "list-select",
        "type": "list",
        "source": "$rows",
        "selectable": true,
        "multiple": true,
        "listItem": {
        "body": [
          {
            "type": "hbox",
            "columns": [
              {
                "label": "Engine",
                "name": "engine"
              },

              {
                "name": "version",
                "label": "Version"
              }
            ]
          }
        ]
      }
    }
    ]
}
]
```

### initDrag & cancelDrag

```schema: scope="body"
[
    {
    "type": "button-toolbar",
    "className": "m-b",
    "buttons": [
    {
        "name": "trigger4",
        "id": "trigger4",
        "type": "action",
        "label": "开启列表行排序",
        "onEvent": {
        "click": {
            "actions": [
            {
                "actionType": "initDrag",
                "componentId": "list-select",
                "description": "点击开启列表行排序功能"
            }
            ]
        }
        }
    },
    {
        "name": "trigger5",
        "id": "trigger5",
        "type": "action",
        "label": "取消列表行排序",
        "onEvent": {
        "click": {
            "actions": [
            {
                "actionType": "cancelDrag",
                "componentId": "list-select",
                "description": "点击取消列表行排序功能"
            }
            ]
        }
        }
    }
    ]
},
{
    "type": "service",
    "api": "/api/mock2/sample?perPage=10",
    "body": [
    {
        "id": "list-select",
        "type": "list",
        "source": "$rows",
        "listItem": {
        "body": [
          {
            "type": "hbox",
            "columns": [
              {
                "label": "Engine",
                "name": "engine"
              },

              {
                "name": "version",
                "label": "Version"
              }
            ]
          }
        ]
      }
    }
    ]
}
]
```

### setValue

#### 更新列表记录

```
/* Detailed source-code truncated for AI context efficiency. */
```

#### 更新指定行记录

可以通过指定`index`或者`condition`来分别更新指定索引的行记录和指定满足条件（条件表达式或者 ConditionBuilder）的行记录，另外`replace`同样生效，即可以完全替换指定行记录，也可以对指定行记录做合并。

```
/* Detailed source-code truncated for AI context efficiency. */
```

---

### Zh CN Components Log (`docs/zh-CN/components/log.md`)

---
title: Log 实时日志
description:
type: 0
group: ⚙ 组件
menuName: Log
icon:
order: 56
---

用于实时显示日志或程序输出结果。

## 基本用法

通过设置 source 来获取日志，支持 ANSI 基本颜色显示。

```json
{
  "type": "log",
  "height": 300,
  "source": "http://localhost:3000/"
}
```

由于缺少线上服务，所以这个例子无法在线演，它的运行效果如下图所示



### 后端实现参考

后端需要通过流的方式输出结果，比如 Node 实现示例：

```javascript
const http = require('http');

let app = http.createServer((req, res) => {
  res.writeHead(200, {
    'Content-Type': 'text/plain',
    'Access-Control-Allow-Origin': 'http://localhost:8888',
    'Access-Control-Allow-Methods': 'POST, GET, OPTIONS',
    'Access-Control-Allow-Credentials': 'true',
    'Access-Control-Allow-Headers': '*'
  });

  let index = 1;
  let timer = setInterval(() => {
    if (index < 50) {
      // 每次 write 都会立刻传给前端
      res.write(`line: ${index}\n`);
      index += 1;
    } else {
      res.end('end');
      clearInterval(timer);
    }
  }, 100);
});

app.listen(3000, '127.0.0.1');
console.log('Node server running on port 3000');
```

其它语言请查找如何使用 stream 的方式返回内容，比如 Spring 的 `StreamingResponseBody`：

```java
@Controller
public class StreamingResponseBodyController {
    @GetMapping("/logs")
    public ResponseEntity<StreamingResponseBody> handleLog() {
        StreamingResponseBody stream = out -> {
          for (int i = 0; i < 1000; i++) {
            String msg = "log" + " @ " + new Date();
            out.write(msg.getBytes());
            out.flush();
          }
          out.close();
        };
        return new ResponseEntity(stream, HttpStatus.OK);
    }
}
```

需要注意有些反向代理有 buffer 设置，比如 nginx 的 [proxy_buffer_size](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffer_size)，它会使得即便后端返回内容也需要等 buffer 满了才会真正返回前端，如果需要更实时的效果就需要关掉此功能。

### 轮询方案

如果后端无法提供流的方式，也可以通过轮询的方式获取数据，比如：

```schema
{
  "type": "page",
  "title": "轮询日志演示，当秒钟到 59 时会停止轮询",
  "body": [
    {
      "type": "service",
      "api": {
        "method": "get",
        "url": "/api/mock2/log/date?offset=${offset}",
        "autoRefresh": false, // 因为设置了轮询，所以关闭自动刷新
        "concatDataFields": "log"
      },
      "silentPolling": true,
      "interval": 1000,
      "stopAutoRefreshWhen": "${finished}",
      "body": [
        {
          "type": "log",
          "height": 300,
          "source": "${log}"
        }
      ]
    }
  ]
}
```

此示例利用了 Service 组件的轮询能力，并通过 `concatDataFields` 将多次返回的日志拼接起来，然后通过给 log 设置 `source` 属性来关联日志数据。

## 对于超长日志的优化

> 1.10.0 及以上版本

如果日志非常长会导致页面卡顿，这时有几种处理方法，请根据需求进行选择，也可以都使用：

1. 设置 `rowHeight`，比如 `"rowHeight": 22`，这时就会默认启用虚拟渲染，避免渲染卡顿
   - 优点：仍然可以查看所有日志
   - 缺点：如果某一行日志很长也不会自动折行，会出现水平滚动条；目前暂时不支持 autoScroll
2. 设置 `maxLength`，限制最大显示行数
   - 优点：某一行日志很长的时候会自动折行
   - 缺点：无法查看之前的日志

## 自动滚动到底部

通过 `autoScroll` 可以关闭此功能

## source 支持变量

> 1.4.2 及以上版本

可以初始设置为空，这样初始不会加载，而等这个变量有值的时候再加载

```json
{
  "type": "form",
  "body": [
    {
      "label": "数据源",
      "type": "select",
      "name": "source",
      "options": [
        {
          "label": "A",
          "value": "http://localhost:3000/"
        },
        {
          "label": "B",
          "value": "http://localhost:4000/"
        }
      ]
    },
    {
      "type": "log",
      "height": 300,
      "placeholder": "请点击上面的数据源",
      "source": "${source | raw}"
    }
  ]
}
```

## source 支持高级配置

> 1.6.1 及以上版本

可以类似 api 那样自定义 header、method 等，比如：

```json
{
  "type": "log",
  "height": 300,
  "source": {
    "method": "post",
    "url": "[/api/mock2/form/saveForm](http://localhost:3000/)",
    "data": {
      "myName": "${name}",
      "myEmail": "${email}"
    },
    "headers": {
      "my-header": "${myHeader}"
    }
  }
}
```

## 属性表

| 属性名       | 类型      | 默认值    | 说明                                                              |
| ------------ | --------- | --------- | ----------------------------------------------------------------- |
| height       | `number`  | 500       | 展示区域高度                                                      |
| className    | `string`  |           | 外层 CSS 类名                                                     |
| autoScroll   | `boolean` | true      | 是否自动滚动                                                      |
| disableColor | `boolean` | false     | 是否禁用 ansi 颜色支持                                            |
| placeholder  | `string`  |           | 加载中的文字                                                      |
| encoding     | `string`  | utf-8     | 返回内容的字符编码                                                |
| source       | `string`  |           | 接口                                                              |
| credentials  | `string`  | 'include' | fetch 的 credentials 设置                                         |
| rowHeight    | `number`  |           | 设置每行高度，将会开启虚拟渲染                                    |
| maxLength    | `number`  |           | 最大显示行数                                                      |
| operation    | `Array`   |           | 可选日志操作：['stop','restart',clear','showLineNumber','filter'] |

---

### Zh CN Components Mapping (`docs/zh-CN/components/mapping.md`)

---
title: Mapping 映射
description:
type: 0
group: ⚙ 组件
menuName: Mapping 映射
icon:
order: 57
---

## 基本用法

```schema
{
    "type": "page",
    "body": {
        "type": "mapping",
        "value": "1",
        "map": {
            "1": "第一",
            "2": "第二",
            "3": "第三",
            "*": "其他"
        }
    }
}
```

## 渲染 HTML

```schema
{
    "type": "page",
    "body": {
        "type": "mapping",
        "value": "2",
        "map": {
            "1": "<span class='label label-info'>漂亮</span>",
            "2": "<span class='label label-success'>开心</span>",
            "3": "<span class='label label-danger'>惊吓</span>",
            "4": "<span class='label label-warning'>紧张</span>",
            "*": "<span class='label label-default'>其他：${type}</span>"
        }
    }
}
```

## 渲染其它组件

映射的值也可以是 amis schema，渲染其它组件

> 配置了`itemSchema`后，映射值不会再作为`schema`渲染

```schema
{
    "type": "page",
    "body": {
        "type": "mapping",
        "value": "1",
        "map": {
            "1":  {
                "type": "tag",
                "label": "#4096ff",
                "displayMode": "rounded",
                "color": "#4096ff"
            },
            "2":  {
                "type": "tpl",
                "tpl": "2"
            },
            "*": "其他"
        }
    }
}
```

## 渲染 自定义模板

> since 2.5.2

可配置`itemSchema` 渲染自定义模板，支持`HTML`或`schema`；  
当映射值是`非object`时，可使用`${item}`获取映射值；

### html 或字符串模板

使用`${item}` 获取映射值

```schema
{
    "type": "page",
    "body": {
        "type": "mapping",
        "value": "1",
        "map": {
            "1": "第一",
            "2": "第二",
            "3": "第三",
            "*": "其他"
        },
        "itemSchema": "自定义模板：<span style='color: red'>${item}</span>"
    }
}
```

### SchemaNode 模板

```schema
{
    "type": "page",
    "body": {
        "type": "mapping",
        "value": "1",
        "map": {
            "1": "第一",
            "2": "第二",
            "3": "第三",
            "*": "其他"
        },
        "itemSchema": {
            "type": "tag",
            "label": "${item}"
        }
    }
}
```

### 在模板中渲染数据

- 当映射值是`object`时，使用模板语法可获取`object`属性值
- 当映射值是`非object`时，使用`${item}` 获取映射值
- 也可以获取数据域中的其他数据

```schema
{
    "type": "page",
    "data": {
        "myName": "cat"
    },
    "body": {
        "type": "mapping",
        "value": "1",
        "map": {
            "1": {
                "label": "开心",
                "color": "red"
            },
            "2": {
                "label": "伤心",
                "color": "blue"
            },
            "3": {
                "label": "冷漠",
                "color": "gray"
            },
            "*": "其他"
        },
        "itemSchema": {
            "type": "tag",
            "label": "${myName} ${label}",
            "color": "${color}"
        }
    }
}
```

## 映射展示多个

> 1.5.0 及以上版本

如果返回值是数组会显示为多个

```schema
{
    "type": "page",
    "body": {
        "type": "mapping",
        "value": ["1", "2", "3", "4", "5"],
        "map": {
            "1": "<span class='label label-info'>漂亮</span>",
            "2": "<span class='label label-success'>开心</span>",
            "3": "<span class='label label-danger'>惊吓</span>",
            "4": "<span class='label label-warning'>紧张</span>",
            "*": "<span class='label label-default'>其他</span>"
        }
    }
}
```

## map 映射源

### k-v 对象

```json
{
  "type": "mapping",
  "value": "1",
  "map": {
    "1": "第一",
    "2": "第二",
    "3": "第三",
    "*": "其他"
  }
}
```

### 对象数组

> since 2.5.2

#### 简单对象数组

```json
{
  "type": "mapping",
  "value": "1",
  "map": [{"1": "第一"}, {"2": "第二"}, {"3": "第三"}, {"*": "其他"}]
}
```

#### 多 key 对象数组

当映射值有多个 key 时，需要使用`valueField`指定字段作为`mapping`的`key`, 也就是用来匹配`value`的值  
可使用`labelField`指定展示字段，不配置时，默认为`label`  
**注意：**配置`labelField`后，映射值无法再作为`schema`渲染

```json
{
  "type": "mapping",
  "value": "happy",
  "valueField": "name",
  "map": [
    {
      "name": "happy",
      "label": "开心"
    },
    {
      "name": "sad",
      "label": "悲伤"
    },
    {
      "name": "*",
      "label": "其他"
    }
  ]
}
```

```schema
{
    "type": "page",
    "body": {
        "type": "mapping",
        "value": "happy",
        "valueField": "name",
        "labelField": "label",
        "map": [
            {
                "name": "happy",
                "label": "开心",
                "color": "red"
            },
            {
                "name": "sad",
                "label": "悲伤",
                "color": "blue"
            },
            {
                "name": "*",
                "label": "其他",
                "color": "gray"
            }
        ]
    }
}
```

## 用作 Field 时

当用在 Table 的列配置 Column、List 的内容、Card 卡片的内容和表单的 Static-XXX 中时，可以设置`name`属性，映射同名变量

### Table 中的列类型

```schema: scope="body"
{
    "type": "table",
    "data": {
        "items": [
            {
                "id": "1",
                "type": "1"
            },
            {
                "id": "2",
                "type": "2"
            },
            {
                "id": "3",
                "type": "3"
            }
        ]
    },
    "columns": [
        {
            "name": "id",
            "label": "Id"
        },
        {
            "name": "type",
            "label": "映射",
            "type": "mapping",
            "map": {
                "1": "<span class='label label-info'>漂亮</span>",
                "2": "<span class='label label-success'>开心</span>",
                "3": "<span class='label label-danger'>惊吓</span>",
                "4": "<span class='label label-warning'>紧张</span>",
                "*": "其他：${type}"
            }
        }
    ]
}
```

List 的内容、Card 卡片的内容配置同上

### Form 中静态展示

```schema: scope="body"
{
    "type": "form",
    "data": {
        "type": "2"
    },
    "body": [
        {
            "type": "static-mapping",
            "name": "type",
            "label": "映射",
            "map": {
                "1": "<span class='label label-info'>漂亮</span>",
                "2": "<span class='label label-success'>开心</span>",
                "3": "<span class='label label-danger'>惊吓</span>",
                "4": "<span class='label label-warning'>紧张</span>",
                "*": "其他：${type}"
            }
        }
    ]
}
```

### 布尔值映射

```schema: scope="body"
{
    "type": "form",
    "data": {
        "type": true
    },
    "body": [
        {
            "type": "static-mapping",
            "name": "type",
            "label": "映射",
            "map": {
                "1": "<span class='label label-info'>开</span>",
                "0": "<span class='label label-default'>关</span>"
            }
        }
    ]
}
```

或者

```schema: scope="body"
{
    "type": "form",
    "data": {
        "type": true
    },
    "body": [
        {
            "type": "static-mapping",
            "name": "type",
            "label": "映射",
            "map": {
                "true": "<span class='label label-info'>开</span>",
                "false": "<span class='label label-default'>关</span>"
            }
        }
    ]
}
```

### 远程拉取字典

> since 1.1.6

通过配置 `source` 接口来实现，接口返回字典对象即可，数据格式参考 map 配置。

```schema: scope="body"
{
    "type": "form",
    "data": {
        "type": "2"
    },
    "body": [
        {
            "type": "mapping",
            "name": "type",
            "label": "映射",
            "source": "/api/mapping"
        }
    ]
}
```

> 默认 source 是有 30s 缓存的，通常字典数据不长变更。如果想修改，请参考 [API](../../../docs/types/api) 文档配置缓存。

### 关联上下文变量

> since 1.1.6

同样通过配置 `source` 来实现，只是格式是取变量。

> 注意：当数据域里的变量值为`$$`时, 表示将所有接口返回的`data`字段值整体赋值到对应的 key 中

```schema: scope="body"
{
    "type": "form",
    "initApi": {
        "url": "/api/mapping",
        "method": "get",
        "responseData": {
            "zidian": "$$$$",
            "type": "2"
        }
    },
    "body": [
        {
            "type": "mapping",
            "name": "type",
            "label": "映射",
            "source": "$${zidian}"
        }
    ]
}
```

## 占位文本

通过 `placeholder` 可以控制数据不存在时的展现

```schema
{
    "type": "page",
    "body": {
        "type": "mapping",
        "placeholder": "数据不存在",
        "map": {
            "1": "第一",
            "2": "第二",
            "3": "第三",
            "*": "其他"
        }
    }
}
```

## 属性表

| 属性名      | 类型                                                | 默认值 | 说明                                                                                                                                                                                                                                        |
| ----------- | --------------------------------------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| className   | `string`                                            |        | 外层 CSS 类名                                                                                                                                                                                                                               |
| placeholder | `string`                                            |        | 占位文本                                                                                                                                                                                                                                    |
| map         | `object`或`Array<object>`                           |        | 映射配置                                                                                                                                                                                                                                    |
| source      | `string` or `API`                                   |        | [API](../../../docs/types/api) 或 [数据映射](../../../docs/concepts/data-mapping)                                                                                                                                                           |
| valueField  | `string`                                            | value  | `2.5.2` map 或 source 为`Array<object>`时，用来匹配映射的字段名                                                                                                                                                                             |
| labelField  | `string`                                            | label  | `2.5.2` map 或 source 为`Array<object>`时，用来展示的字段名<br />注：配置后映射值无法作为`schema`组件渲染                                                                                                                                   |
| itemSchema  | `string`或[SchemaNode](../../docs/types/schemanode) |        | `2.5.2` 自定义渲染模板，支持`html`或`schemaNode`；<br /> 当映射值是`非object`时，可使用`${item}`获取映射值；<br />当映射值是`object`时，可使用映射语法: `${xxx}`获取`object`的值；<br /> 也可使用数据映射语法：`${xxx}`获取数据域中变量值。 |

---

### Zh CN Components Markdown (`docs/zh-CN/components/markdown.md`)

---
title: Markdown 渲染
description:
type: 0
group: ⚙ 组件
menuName: Markdown 渲染
icon:
order: 58
---

> 1.1.6 版本开始

## 基本用法

```schema
{
    "type": "page",
    "body": {
        "type": "markdown",
        "value": "# title\n markdown **text**"
    }
}
```

## 动态数据

动态数据可以通过 name 来关联，类似 [static](form/static) 组件

## 基于 Editor 和数据联动来实现预览功能

```schema: scope="body"
{
    "type": "form",
    "api": "/api/mock2/form/saveForm",
    "body": [
        {
            "type": "group",
            "body": [
                {
                    "type": "editor",
                    "name": "md",
                    "language": "markdown"
                },
                {
                    "type": "markdown",
                    "name": "md"
                }
            ]
        }

    ]
}
```

## 加载外部 markdown 文件

> 1.6.5 及以上版本

可以通过 `src` 属性来加载外部 markdown 文件，比如

```schema: scope="body"
{
    "type": "markdown",
    "src": "/api/mock2/sample/mirror?json=%7B%22status%22%3A0%2C%22data%22%3A%22%23%23%20title%20%5Cn%20content%22%7D"
}
```

这个接口的返回格式可以是两种，一种是 JSON，类似

```
{
    "status": 0,
    "msg": "",
    "data": "markdown"
}
```

另一种是返回 `content-type` 为 `text/markdown` 或 `text/x-markdown` 的纯文本。

## 视频

可以使用 `` 语法来嵌入视频。

## 支持 latex

> 3.6.0 及以上版本

公式渲染使用 KaTeX 实现，由于体积太大默认不提供，需要自己去[下载](https://github.com/KaTeX/KaTeX/releases)，在页面中引入以下三个文件：

```
<link rel="stylesheet" href="katex/katex.min.css">
<script src="katex/katex.min.js"></script>
<script src="katex/contrib/auto-render.min.js"></script>
```

markdown 中的 `$` 或 `$$` 包裹的内容就能以公式展现，比如 `$\sqrt{a^2 + b^2}$`，如果是在代码中 `\` 要转义为 `\\`

```schema
{
    "type": "page",
    "body": {
        "type": "markdown",
        "value": "$$\\hat{f} (\\xi)=\\int_{-\\infty}^{\\infty}f(x)e^{-2\\pi ix\\xi}dx$$"
    }
}
```

## 高级配置

> 1.8.1 及以上版本

有以下配置：

- html，是否支持 html 标签，默认 false
- linkify，是否自动识别链接，默认值是 true
- breaks，是否回车就是换行，默认 false

```schema
{
    "type": "page",
    "body": {
        "type": "markdown",
        "value": "# title\n <b>markdown</b>\n http://www.github.com/",
        "options": {
            linkify: false,
            html: true,
            breaks: true
        }
    }
}
```

## 属性表

| 属性名    | 类型     | 默认值 | 说明     |
| --------- | -------- | ------ | -------- |
| name      | `string` |        | 名称     |
| value     | `string` |        | 静态值   |
| className | `string` |        | 类名     |
| src       | `Api`    |        | 外部地址 |

---

### Zh CN Components Nav (`docs/zh-CN/components/nav.md`)

---
title: Nav 导航
description:
type: 0
group: ⚙ 组件
menuName: Nav
icon:
order: 58
---

用于展示链接导航

## 基本用法

```schema: scope="body"
{
  "type": "nav",
  "stacked": true,
  "className": "w-md",
  "itemBadge": {
    "mode": "ribbon",
    "text": "${customText}",
    "position": "top-left",
    "visibleOn": "this.customText",
    "level": "${customLevel}"
  },
  "links": [
    {
      "label": "Nav 1",
      "to": "/docs/index",
      "icon": "https://suda.cdn.bcebos.com/images%2F2021-01%2Fdiamond.svg",
      "active": true
    },
    {
      "label": "Nav 2",
      "to": "/docs/api",
      "customText": "HOT",
      "customLevel": "danger"
    },
    {
      "label": "Nav 3",
      "to": "/docs/renderers",
      "customText": "SUC",
      "customLevel": "success"
    },
    {
      "label": "外部地址",
      "to": "http://www.baidu.com/",
      "target": "_blank"
    }
  ]
}
```

## 配置多层级

```schema: scope="body"
{
  "type": "nav",
  "stacked": true,
  "className": "w-md",
  "links": [
    {
      "label": "Nav 1",
      "to": "/docs/index",
      "icon": "fa fa-user",
      "active": true
    },
    {
      "label": "Nav 2",
      "unfolded": true,
      "children": [
        {
          "label": "Nav 2-1",
          "children": [
            {
              "label": "Nav 2-1-1",
              "to": "/docs/api-2-1-1"
            }
          ]
        },
        {
          "label": "Nav 2-2",
          "to": "/docs/api-2-2"
        }
      ]
    },
    {
      "label": "Nav 3",
      "to": "/docs/renderers"
    }
  ]
}
```

## 横向摆放

```schema: scope="body"
{
  "type": "nav",
  "stacked": false,
  "links": [
    {
      "label": "Nav 1",
      "to": "/docs/index",
      "icon": "fa fa-user"
    },
    {
      "label": "Nav 2",
      "to": "/docs/api"
    },
    {
      "label": "Nav 3",
      "to": "/docs/renderers"
    }
  ]
}
```

### 响应式收纳

横向（`"stack": false`）模式下配置`overflow`，实现导航响应式收纳。

```schema: scope="body"
{
  "type": "nav",
  "stacked": false,
  "overflow": {
    "enable": true
  },
  "links": [
    {
      "label": "Nav 1",
      "to": "?to=nav1"
    },
    {
      "label": "Nav 2",
      "to": "?to=nav1"
    },
    {
      "label": "Nav 3",
      "to": "?to=nav3"
    },
    {
      "label": "Nav 4",
      "to": "?to=nav4"
    },
    {
      "label": "Nav 5",
      "to": "?to=nav5"
    },
    {
      "label": "Nav 6",
      "to": "?to=nav6"
    },
    {
      "label": "Nav 7",
      "to": "?to=nav7"
    },
    {
      "label": "Nav 8",
      "to": "?to=nav8"
    },
    {
      "label": "Nav 9",
      "to": "?to=nav9"
    },
    {
      "label": "Nav 10",
      "to": "?to=nav10"
    },
    {
      "label": "Nav 11",
      "to": "?to=nav11",
      "children": [
        {
          "label": "Nav 13",
          "to": "?to=nav13"
        }
      ]
    },
    {
      "label": "Nav 12",
      "to": "?to=nav12"
    }
  ]
}
```

设置`maxVisibleCount`可以自定义强制展示的导航数量，不设置则自动处理。设置`overflowIndicator`自定义菜单按钮的图标。
设置`overflowLabel`自定义菜单按钮文本。

```schema: scope="body"
{
  "type": "nav",
  "stacked": false,
  "overflow": {
    "enable": true,
    "overflowClassName": "nav-overflow-btn",
    "overflowPopoverClassName": "nav-overflow-popover",
    "overflowIndicator": "fas fa-angle-double-down",
    "overflowLabel": "更多",
    "maxVisibleCount": 5
  },
  "links": [
    {
      "label": "Nav 1",
      "to": "?to=nav1"
    },
    {
      "label": "Nav 2",
      "to": "?to=nav1"
    },
    {
      "label": "Nav 3",
      "to": "?to=nav3"
    },
    {
      "label": "Nav 4",
      "to": "?to=nav4"
    },
    {
      "label": "Nav 5",
      "to": "?to=nav5"
    },
    {
      "label": "Nav 6",
      "to": "?to=nav6"
    },
    {
      "label": "Nav 7",
      "to": "?to=nav7"
    },
    {
      "label": "Nav 8 Nav 8 Nav 8 Nav 8 Nav 8",
      "to": "?to=nav8"
    }
  ]
}
```

横向导航默认使用下拉框收纳折叠的导航，设置`overflow.mode`为`swipe`可以使用左右滚动收纳。

```schema: scope="body"
{
    type: 'nav',
    stacked: false,
    overflow: {
      enable: true,
      mode: 'swipe'
    },
    links: [
      {
        label: 'Nav 1',
        to: '?to=nav1'
      },
      {
        label: 'Nav 2',
        to: '?to=nav2'
      },
      {
        label: 'Nav 3',
        to: '?to=nav3'
      },
      {
        label: 'Nav 4',
        to: '?to=nav4'
      },
      {
        label: 'Nav 5',
        to: '?to=nav5'
      },
      {
        label: 'Nav 6',
        to: '?to=nav6'
      },
      {
        label: 'Nav 7',
        to: '?to=nav7'
      },
      {
        label: 'Nav 8',
        to: '?to=nav8'
      },
      {
        label: 'Nav 9',
        to: '?to=nav9'
      },
      {
        label: 'Nav 10',
        to: '?to=nav10'
      },
      {
        label: 'Nav 11',
        to: '?to=nav11',
      },
      {
        label: 'Nav 12',
        to: '?to=nav12'
      },{
        label: 'Nav 13',
        to: '?to=nav13'
      },{
        label: 'Nav 14',
        to: '?to=nav14'
      },{
        label: 'Nav 15',
        to: '?to=nav15'
      },{
        label: 'Nav 16',
        to: '?to=nav16'
      },{
        label: 'Nav 17',
        to: '?to=nav17'
      },{
        label: 'Nav 18',
        to: '?to=nav18'
      },{
        label: 'Nav 19',
        to: '?to=nav19'
      }
    ]
  }
```

### 导航项收纳

垂直（`"stack": true`）模式下，如果子导航项比较多，也可以给导航项设置收纳模式，配置同`overflow`，仅支持一次性展开

```schema: scope="body"
{
  "type": "nav",
  "stacked": true,
  "expandPosition": "after",
  "style": {
    "width": 200
  },
  "links": [
    {
      "label": [
        {
          "type": "tpl",
          "tpl": "Nav1"
        }
      ],
      "to": "#/"
    },
    {
      "label": "Nav2",
      "unfolded": true,
      "overflow": {
        "enable": true
      },
      "children": [
        {
          "label": "Nav 2-1",
          "to": "#/test2"
        },
        {
          "label": "Nav 2-2",
          "to": "#/test3"
        },
        {
          "label": "Nav 2-3",
          "to": "#/test1"
        },
        {
          "label": "Nav 2-4",
          "to": "#/test4"
        },
        {
          "label": "Nav 2-5",
          "to": "#/test5"
        }
      ]
    }
  ]
}
```

## 动态导航

通过配置 source 来实现动态生成导航，source 可以是 api 地址或者变量，比如

```schema
{
  "type": "page",
  "data": {
    "nav": [
      {
        "label": "Nav 1",
        "to": "/docs/index",
        "icon": "fa fa-user"
      },
      {
        "label": "Nav 2",
        "to": "/docs/api"
      },
      {
        "label": "Nav 3",
        "to": "/docs/renderers"
      }
    ]
  },
  "body": {
    "type": "nav",
    "stacked": true,
    "source": "${nav}"
  }
}
```

## 懒加载

可以一次只加载部分层级，更深层次的选项可以标记为 `defer` 为 true，这样只有点开的时才会加载。

```schema: scope="body"
{
  "type": "nav",
  "stacked": true,
  "source": "/api/options/nav?parentId=${value}"
}
```

## 更多操作

```schema: scope="body"
{
  "type": "nav",
  "stacked": true,
  "className": "w-md",
  "draggable": true,
  "saveOrderApi": "/api/options/nav",
  "source": "/api/options/nav?parentId=${value}",
  "style": {
    "width": 160
  },
  "itemActions": [
    {
      "type": "icon",
      "icon": "cloud",
      "visibleOn": "this.to === '?cat=1'"
    },
    {
      "type": "dropdown-button",
      "level": "link",
      "icon": "fa fa-ellipsis-h",
      "hideCaret": true,
      "buttons": [
        {
          "type": "button",
          "label": "编辑"
        },
        {
          "type": "button",
          "label": "删除"
        }
      ]
    }
  ]
}
```

## 悬浮导航

可以通过设置`mode`属性来控制导航模式，不设置默认为内联导航模式

```schema: scope="body"
{
  "type": "nav",
  "stacked": true,
  "mode": "float",
  "style": {
    "width": "200px"
  },
  "links": [
    {
      "label": "Nav 1",
      "to": "/docs/index",
      "icon": "fa fa-user",
      "active": true
    },
    {
      "label": "Nav 2",
      "unfolded": true,
      "children": [
        {
          "label": "Nav 2-1",
          "children": [
            {
              "label": "Nav 2-1-1",
              "to": "/docs/api-2-1-1"
            }
          ]
        },
        {
          "label": "Nav 2-2",
          "to": "/docs/api-2-2"
        }
      ]
    },
    {
      "label": "Nav 3",
      "to": "/docs/renderers"
    }
  ]
}
```

## 悬浮面板模式

设置`mode`属性为 panel，开启悬浮面板模式，最多支持 3 级菜单

```
/* Detailed source-code truncated for AI context efficiency. */
```

设置竖向展示

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 导航缩起

`collapsed`属性控制导航的展开和缩起，缩起状态下，导航内容仅展示图标或第一个文字，悬浮展开全部内容或子导航项

```schema: scope="body"
{
  "type": "nav",
  "stacked": true,
  "collapsed": true,
  "links": [
    {
      "label": "Nav 1",
      "to": "/docs/index",
      "icon": "fa fa-user"
    },
    {
      "label": "Nav 2",
      "unfolded": true,
      "children": [
        {
          "label": "Nav 2-1",
          "children": [
            {
              "label": "Nav 2-1-1",
              "to": "/docs/api-2-1-1"
            }
          ]
        },
        {
          "label": "Nav 2-2",
          "to": "/docs/api-2-2"
        }
      ]
    },
    {
      "label": "Nav 3",
      "to": "/docs/renderers"
    }
  ]
}
```

## 导航分割线

导航项`mode`属性控制导航项的展示模式，支持`divider`（分割线）和`group`（分组）两种模式，不设置默认为普通导航项

```schema: scope="body"
{
  "type": "nav",
  "stacked": true,
  "style": {
    "width": "160px"
  },
  "links": [
    {
      "label": "Nav 1",
      "to": "/docs/index",
      "icon": "fa fa-user"
    },
    {
      mode: 'divider'
    },
    {
      "label": "Nav 2",
      "unfolded": true,
      "children": [
        {
          "label": "Nav 2-1",
          "children": [
            {
              "label": "Nav 2-1-1",
              "to": "/docs/api-2-1-1"
            }
          ]
        },
        {
          "label": "Nav 2-2",
          "to": "/docs/api-2-2"
        }
      ]
    },
    {
      "label": "Nav 3",
      "to": "/docs/renderers",
      "disabled": true,
      "disabledTip": "导航项禁用"
    }
  ]
}
```

## 导航分组

分组模式（`"mode": "group"`）的导航项展示为分组标题形式

```schema: scope="body"
{
  "type": "nav",
  "stacked": true,
  "links": [
    {
      "label": "Nav 1",
      "to": "/docs/index",
      "icon": "fa fa-user"
    },
    {
      "label": "Nav 2",
      "unfolded": true,
      "mode": "group",
      "children": [
        {
          "label": "Nav 2-1",
          "children": [
            {
              "label": "Nav 2-1-1",
              "to": "/docs/api-2-1-1"
            }
          ]
        },
        {
          "label": "Nav 2-2",
          "to": "/docs/api-2-2"
        }
      ]
    },
    {
      "label": "Nav 3",
      "to": "/docs/renderers",
      "mode": "group",
      "children": [
        {
          "label": "Nav 3-1",
          "to": "/docs/api-2-1"
        }
      ]
    }
  ]
}
```

## 默认展开层级

当前导航最大层级为 4，可通过`defaultOpenLevel`来控制默认 2 层级全部展开

```schema: scope="body"
{
  "type": "nav",
  "stacked": true,
  "defaultOpenLevel": "2",
  "links": [
    {
      "label": "Nav 1",
      "to": "/docs/index",
      "icon": "fa fa-user"
    },
    {
      "label": "Nav 2",
      "unfolded": true,
      "children": [
        {
          "label": "Nav 2-1",
          "children": [
            {
              "label": "Nav 2-1-1",
              "to": "/docs/api-2-1-1",
              "children": [
                {
                  "label": "Nav 2-1-1-1",
                  "to": "/docs/api-2-1-1-1"
                }
              ]
            }
          ]
        },
        {
          "label": "Nav 2-2",
          "to": "/docs/api-2-2"
        }
      ]
    },
    {
      "label": "Nav 3",
      "to": "/docs/renderers",
      "children": [
        {
          "label": "Nav 3-1",
          "to": "/docs/api-2-1"
        }
      ]
    }
  ]
}
```

## 自定义展开按钮

可以设置`expandIcon`为 icon 的名称字符串

```schema: scope="body"
{
  "type": "nav",
  "stacked": true,
  "expandIcon": "close",
  "links": [
    {
      "label": "Nav 1",
      "to": "/docs/index",
      "icon": "fa fa-user"
    },
    {
      "label": "Nav 2",
      "unfolded": true,
      "children": [
        {
          "label": "Nav 2-1",
          "children": [
            {
              "label": "Nav 2-1-1",
              "to": "/docs/api-2-1-1"
            }
          ]
        },
        {
          "label": "Nav 2-2",
          "to": "/docs/api-2-2"
        }
      ]
    },
    {
      "label": "Nav 3",
      "to": "/docs/renderers",
      "children": [
        {
          "label": "Nav 3-1",
          "to": "/docs/api-2-1"
        }
      ]
    }
  ]
}
```

也可以将`expandIcon`设置为`SchemaObject`

```schema: scope="body"
{
  "type": "nav",
  "stacked": true,
  "expandIcon": {
    "type": "icon",
    "icon": "far fa-address-book"
  },
  "links": [
    {
      "label": "Nav 1",
      "to": "/docs/index",
      "icon": "fa fa-user"
    },
    {
      "label": "Nav 2",
      "unfolded": true,
      "children": [
        {
          "label": "Nav 2-1",
          "children": [
            {
              "label": "Nav 2-1-1",
              "to": "/docs/api-2-1-1"
            }
          ]
        },
        {
          "label": "Nav 2-2",
          "to": "/docs/api-2-2"
        }
      ]
    },
    {
      "label": "Nav 3",
      "to": "/docs/renderers",
      "children": [
        {
          "label": "Nav 3-1",
          "to": "/docs/api-2-1"
        }
      ]
    }
  ]
}
```

## 搜索导航项

> `3.5.0` 及以上版本

开启`"searchable": true`后，支持搜索当前数据源内的导航项，支持自定义匹配函数[`NavMatchFunc`](#navmatchfunc)，如果不设置默认模糊匹配导航对象中的`label`, `title` 和 `key` 字段。

```schema: scope="body"
{
  "type": "container",
  "className": "w-40",
  "body": [
    {
      "type": "nav",
      "stacked": true,
      "searchable": true,
      "searchConfig": {
        "matchFunc": "return link.searchKey === keyword;"
      },
      "links": [
        {
          "label": "Nav 1",
          "to": "?to=nav1",
          "searchKey": "1"
        },
        {
          "label": "Nav 2",
          "to": "?to=nav2",
          "searchKey": "2",
          "children": [
            {
              "label": "Nav 2-1",
              "to": "?to=nav2-1",
              "searchKey": "2-1",
              "children": [
                {
                  "label": "Nav 2-1-1",
                  "to": "?to=nav2-1-1",
                  "searchKey": "2-1-1"
                }
              ]
            }
          ]
        },
        {
          "label": "Nav 3",
          "to": "?to=nav3",
          "searchKey": "3",
          "children": [
            {
              "label": "Nav 3-1",
              "to": "?to=nav3-1",
              "searchKey": "3-1"
            }
          ]
        },
        {
          "label": "Nav 4",
          "to": "?to=nav4",
          "searchKey": "4"
        },
        {
          "label": "Nav 5",
          "to": "?to=nav5",
          "searchKey": "5"
        }
      ]
    }
  ]
}
```

## 属性表

| 属性名                            | 类型                                      | 默认值                          | 说明                                                                                                              | 版本     |
| --------------------------------- | ----------------------------------------- | ------------------------------- | ----------------------------------------------------------------------------------------------------------------- | -------- |
| type                              | `string`                                  | `"nav"`                         | 指定为 Nav 渲染器                                                                                                 |
| mode                              | `string`                                  | `"inline"`                      | 导航模式，悬浮/内联/悬浮面板，默认内联模式                                                                        |
| collapsed                         | `boolean`                                 |                                 | 控制导航是否缩起                                                                                                  |
| indentSize                        | `number`                                  | `16`                            | 层级缩进值，仅内联模式下生效                                                                                      |
| level                             | `number`                                  |                                 | 控制导航最大展示层级数                                                                                            |
| defaultOpenLevel                  | `number`                                  |                                 | 控制导航最大默认展开层级                                                                                          |
| className                         | `string`                                  |                                 | 外层 Dom 的类名                                                                                                   |
| popupClassName                    | `string`                                  |                                 | 当为悬浮模式时，可自定义悬浮层样式                                                                                |
| expandIcon                        | `string \| SchemaObject`                  |                                 | 自定义展开按钮                                                                                                    |
| expandPosition                    | `string`                                  |                                 | 展开按钮位置，`"before"`或者`"after"`，不设置默认在前面                                                           |
| stacked                           | `boolean`                                 | `true`                          | 设置成 false 可以以 tabs 的形式展示                                                                               |
| accordion                         | `boolean`                                 |                                 | 是否开启手风琴模式                                                                                                |
| source                            | `string` 或 [API](../../docs/types/api)   |                                 | 可以通过变量或 API 接口动态创建导航                                                                               |
| deferApi                          | [API](../../docs/types/api)               |                                 | 用来延时加载选项详情的接口，可以不配置，不配置公用 source 接口。                                                  |
| itemActions                       | [SchemaNode](../../docs/types/schemanode) |                                 | 更多操作相关配置                                                                                                  |
| draggable                         | `boolean`                                 |                                 | 是否支持拖拽排序                                                                                                  |
| dragOnSameLevel                   | `boolean`                                 |                                 | 仅允许同层级内拖拽                                                                                                |
| saveOrderApi                      | `string` 或 [API](../../docs/types/api)   |                                 | 保存排序的 api                                                                                                    |
| itemBadge                         | [BadgeSchema](../../components/badge)     |                                 | 角标                                                                                                              |
| links                             | `Array`                                   |                                 | 链接集合                                                                                                          |
| links[x].label                    | `string`                                  |                                 | 名称                                                                                                              |
| links[x].to                       | [模板](../../docs/concepts/template)      |                                 | 链接地址                                                                                                          |
| links[x].target                   | `string`                                  | 链接关系                        |                                                                                                                   |
| links[x].icon                     | `string`                                  |                                 | 图标                                                                                                              |
| links[x].children                 | `Array<link>`                             |                                 | 子链接                                                                                                            |
| links[x].unfolded                 | `boolean`                                 |                                 | 初始是否展开                                                                                                      |
| links[x].active                   | `boolean`                                 |                                 | 是否高亮                                                                                                          |
| links[x].activeOn                 | [表达式](../../docs/concepts/expression)  |                                 | 是否高亮的条件，留空将自动分析链接地址                                                                            |
| links[x].defer                    | `boolean`                                 |                                 | 标记是否为懒加载项                                                                                                |
| links[x].deferApi                 | [API](../../docs/types/api)               |                                 | 可以不配置，如果配置优先级更高                                                                                    |
| links[x].disabled                 | `boolean`                                 |                                 | 是否禁用                                                                                                          |
| links[x].disabledTip              | `string`                                  |                                 | 禁用提示信息                                                                                                      |
| links[x].className                | `string`                                  |                                 | 菜单项自定义样式                                                                                                  |
| links[x].mode                     | `string`                                  |                                 | 菜菜单项模式，分组模式：`"group"`、分割线：`"divider"`                                                            |
| links[x].overflow                 | `NavOverflow`                             |                                 | 导航项响应式收纳配置                                                                                              |
| overflow                          | `NavOverflow`                             |                                 | 响应式收纳配置                                                                                                    |
| overflow.enable                   | `boolean`                                 | `false`                         | 是否开启响应式收纳                                                                                                |
| overflow.overflowLabel            | `string \| SchemaObject`                  |                                 | 菜单触发按钮的文字                                                                                                |
| overflow.overflowIndicator        | `SchemaIcon`                              | `"fa fa-ellipsis"`              | 菜单触发按钮的图标                                                                                                |
| overflow.maxVisibleCount          | `number`                                  |                                 | 开启响应式收纳后导航最大可显示数量，超出此数量的导航将被收纳到下拉菜单中，默认为自动计算                          |
| overflow.wrapperComponent         | `string`                                  |                                 | 包裹导航的外层标签名，可以使用其他标签渲染                                                                        |
| overflow.style                    | `React.CSSProperties`                     |                                 | 自定义样式                                                                                                        |
| overflow.overflowClassName        | `string`                                  | `""`                            | 菜单按钮 CSS 类名                                                                                                 |
| overflow.overflowPopoverClassName | `string`                                  | `""`                            | Popover 浮层 CSS 类名                                                                                             |
| overflow.mode                     | `swipe \| popup`                          | `"popup"`                       | 导航超长时使用滚动模式还是浮层收纳模式。默认为 `"popup"`模式。使用 `"swipe"` 模式时，`"maxVisibleCount"` 将失效。 | `6.13.0` |
| searchable                        | `boolean`                                 | `false`                         | 是否开启搜索                                                                                                      | `3.5.0`  |
| searchConfig.matchFunc            | `string`                                  | [`NavMatchFunc`](#navmatchfunc) | 自定义匹配函数, 默认模糊匹配导航对象中的`label`, `title` 和 `key` 字段                                            | `3.5.0`  |
| searchConfig.className            | `string`                                  | `""`                            | 搜索框外层 CSS 类名                                                                                               | `3.5.0`  |
| searchConfig.placeholder          | `string`                                  | `false`                         | 是否开启搜索                                                                                                      | `3.5.0`  |
| searchConfig.mini                 | `boolean`                                 | `false`                         | 是否为 mini 模式                                                                                                  | `3.5.0`  |
| searchConfig.enhance              | `boolean`                                 | `false`                         | 是否为增强样式                                                                                                    | `3.5.0`  |
| searchConfig.clearable            | `boolean`                                 | `false`                         | 是否开启搜索                                                                                                      | `3.5.0`  |
| searchConfig.searchImediately     | `boolean`                                 | `false`                         | 是否立即搜索                                                                                                      | `3.5.0`  |

### NavMatchFunc

```typescript
interface NavMatchFunc {
  (
    /* 导航项对象 */
    link: Link,
    /* 搜索关键字 */
    keyword: string
  ): boolean;
}
```

## 事件表

当前组件会对外派发以下事件，可以通过`onEvent`来监听这些事件，并通过`actions`来配置执行的动作，在`actions`中可以通过`${事件参数名}`或`${event.data.[事件参数名]}`来获取事件产生的数据，详细查看[事件动作](../../docs/concepts/event-action)。

| 事件名称  | 事件参数                                                        | 说明                     |
| --------- | --------------------------------------------------------------- | ------------------------ |
| loaded    | `items: item[]` 数据源<br/>`item?: object` 懒加载时所点击导航项 | 异步加载数据源完成时触发 |
| collapsed | `collapsed: boolean` 缩起展开状态                               | 导航缩起展开时触发       |
| toggled   | `item: object` 导航项数据<br/>`open: boolean` 展开状态          | 点击导航展开按钮时触发   |
| change    | `value: item[]` 选中导航项数据                                  | 导航项选中有变化时触发   |
| click     | `item: object` 点击导航项数据                                   | 手动点击导航项时触发     |

### loaded

数据源加载完成，可以尝试将`source`配置为 api 地址或者开启懒加载。

```schema
{
  "type": "page",
  "body": [
    {
      "type": "action",
      "label": "刷新",
      "onEvent": {
        "click": {
          "actions": [
            {
              "actionType": "reload",
              "componentId": "test"
            }
          ]
        }
      }
    },
    {
      "id": "test",
      "type": "nav",
      "stacked": true,
      "valueField": "label",
      "source": "/api/options/nav?parentId=${value}",
      "onEvent": {
        "loaded": {
          "actions": [
            {
              "actionType": "toast",
              "args": {
                "msg": "已加载${event.data.items.length}条记录"
              }
            }
          ]
        }
      }
    }
  ]
}
```

### collapsed

导航缩起，可以尝试修改导航的`collapsed`属性。

```schema: scope="body"
{
  "type": "nav",
  "stacked": true,
  "collapsed": true,
  "links": [
    {
      "label": "Nav 1",
      "to": "/docs/index",
      "icon": "fa fa-user"
    },
    {
      "label": "Nav 2",
      "unfolded": true,
      "children": [
        {
          "label": "Nav 2-1",
          "children": [
            {
              "label": "Nav 2-1-1",
              "to": "/docs/api-2-1-1"
            }
          ]
        },
        {
          "label": "Nav 2-2",
          "to": "/docs/api-2-2"
        }
      ]
    },
    {
      "label": "Nav 3",
      "to": "/docs/renderers"
    }
  ],
  "onEvent": {
    "collapsed": {
      "actions": [
        {
          "actionType": "toast",
          "args": {
            "msg": "${event.data.collapsed ? '导航缩起' : '导航展开'}"
          }
        }
      ]
    }
  }
}
```

### toggled

导航项收起展开，可以尝试点击导航项展开按钮。

```schema: scope="body"
{
  "type": "nav",
  "stacked": true,
  "links": [
    {
      "label": "Nav 1",
      "to": "/docs/index",
      "icon": "fa fa-user"
    },
    {
      "label": "Nav 2",
      "unfolded": true,
      "children": [
        {
          "label": "Nav 2-1",
          "children": [
            {
              "label": "Nav 2-1-1",
              "to": "/docs/api-2-1-1"
            }
          ]
        },
        {
          "label": "Nav 2-2",
          "to": "/docs/api-2-2"
        }
      ]
    },
    {
      "label": "Nav 3",
      "to": "/docs/renderers"
    }
  ],
  "onEvent": {
    "toggled": {
      "actions": [
        {
          "actionType": "toast",
          "args": {
            "msg": "${event.data.item.label}${event.data.open ? '展开' : '收起'}"
          }
        }
      ]
    }
  }
}
```

### change

导航项选中，可以尝试手动修改任意导航项的`active`属性。

```schema: scope="body"
{
  "type": "nav",
  "stacked": true,
  "links": [
    {
      "label": "Nav 1",
      "to": "/docs/index",
      "icon": "fa fa-user"
    },
    {
      "label": "Nav 2",
      "unfolded": true,
      "children": [
        {
          "label": "Nav 2-1",
          "children": [
            {
              "label": "Nav 2-1-1",
              "to": "/docs/api-2-1-1"
            }
          ]
        },
        {
          "label": "Nav 2-2",
          "to": "/docs/api-2-2"
        }
      ]
    },
    {
      "label": "Nav 3",
      "to": "/docs/renderers"
    }
  ],
  "onEvent": {
    "change": {
      "actions": [
        {
          "actionType": "toast",
          "args": {
            "msg": "${event.data.value.length}项选中"
          }
        }
      ]
    }
  }
}
```

### click

导航项点击，可以尝试手动点击任意导航项。

```schema: scope="body"
{
  "type": "nav",
  "stacked": true,
  "links": [
    {
      "label": "Nav 1",
      "icon": "fa fa-user"
    },
    {
      "label": "Nav 2",
      "children": [
        {
          "label": "Nav 2-1",
          "children": [
            {
              "label": "Nav 2-1-1"
            }
          ]
        },
        {
          "label": "Nav 2-2"
        }
      ]
    },
    {
      "label": "Nav 3"
    }
  ],
  "onEvent": {
    "click": {
      "actions": [
        {
          "actionType": "toast",
          "args": {
            "msg": "${event.data.item.label}被点击了，但不一定选中"
          }
        }
      ]
    }
  }
}
```

## 动作表

当前组件对外暴露以下特性动作，其他组件可以通过指定`actionType: 动作名称`、`componentId: 该组件id`来触发这些动作，动作配置可以通过`args: {动作配置项名称: xxx}`来配置具体的参数，详细请查看[事件动作](../../docs/concepts/event-action#触发其他组件的动作)。

| 动作名称    | 动作配置                         | 说明                                                                                    |
| ----------- | -------------------------------- | --------------------------------------------------------------------------------------- |
| updateItems | `value: string`或`value: item[]` | 更新导航数据源为指定导航项的子导航数据                                                  |
| reset       |                                  | 重置导航数据源，和 updateItems 搭配使用，没有经过 updateItems 操作的，执行 reset 无效果 |

### updateItems / reset

```
/* Detailed source-code truncated for AI context efficiency. */
```

---

### Zh CN Components Number (`docs/zh-CN/components/number.md`)

---
title: Number 数字展示
description:
type: 0
group: ⚙ 组件
menuName: Number
icon:
order: 39
---

用于展示数字

## 基本使用

```schema
{
    "type": "page",
    "body": {
        "type": "number",
        "value": "1591326307",
        "kilobitSeparator": true
    }
}
```

## 配置精度

配置 `precision` 属性来控制小数点位数

```schema
{
    "type": "page",
    "body": {
        "type": "number",
        "value": 13525646.295,
        "precision": 2
    }
}
```

## 百分比展示

配置 `percent` 来开启百分比展示，这个属性同时控制小数位数，如果是 `true` 则表示小数点位数为 `0`。

```schema
{
    "type": "page",
    "body": [
      {
          "type": "number",
          "value": 0.8965,
          "percent": true
      },

      {
        type: 'divider'
      },
      {
          "type": "number",
          "value": 0.8965,
          "percent": 1
      }
    ]
}
```

## 前缀、后缀

配置 `prefix` 或者 `affix` 来控制前缀后缀，可以用来实现单位效果。

```schema
{
    "type": "page",
    "body": [
      {
          "type": "number",
          "value": 1589.98,
          "prefix": '￥'
      },

      {
        type: 'divider'
      },

      {
          "type": "number",
          "value": 1589.98,
          "affix": '公里'
      }
    ]
}
```

## inputNumber 静态展示

inputNumber 配置 `static` 为 `true` 也会通过此组件来展示

```schema
{
    "type": "page",
    "body": [
      {
          "type": "input-number",
          "mode": "horizontal",
          "label": "数字1",
          "name": "num",
          "static": true,
          "value": 1589.98,
          "precision": 2,
          "prefix": '￥'
      },

      {
          "type": "input-number",
          "mode": "horizontal",
          "label": "数字2",
          "name": "num2",
          "static": true,
          "precision": 2,
          "prefix": '￥'
      },

      {
          "type": "input-number",
          "mode": "horizontal",
          "label": "数字3",
          "name": "num3",
          "static": true,
          "placeholder": "无"
      }
    ]
}
```

## 属性表

| 属性名           | 类型                  | 默认值 | 说明                                                                                                                          |
| ---------------- | --------------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------- |
| type             | `string`              |        | 如果在 Table、Card 和 List 中，为`"number"`；在 Form 中用作静态展示，为`"static-number"` 或者 `input-number` 配置 static 属性 |
| className        | `string`              |        | 外层 CSS 类名                                                                                                                 |
| value            | `string`              |        | 数值                                                                                                                          |
| name             | `string`              |        | 在其他组件中，时，用作变量映射                                                                                                |
| placeholder      | `string`              | `-`    | 占位内容                                                                                                                      |
| kilobitSeparator | `boolean`             | `true` | 是否千分位展示                                                                                                                |
| precision        | `number`              |        | 用来控制小数点位数                                                                                                            |
| percent          | `boolean` \| `number` |        | 是否用百分比展示，如果是数字，还可以控制百分比小数点位数                                                                      |
| prefix           | `string`              |        | 前缀                                                                                                                          |
| affix            | `string`              |        | 后缀                                                                                                                          |

---

### Zh CN Components Office Viewer Excel (`docs/zh-CN/components/office-viewer-excel.md`)

---
title: Office Viewer Excel
description:
type: 0
group: ⚙ 组件
menuName: OfficeViewer Excel 渲染
icon:
order: 24
---

> 6.3 及以上版本

## 基本用法

```schema: scope="body"
{
  "type": "office-viewer",
  "src": "/examples/static/all.xlsx",
  "excelOptions": {
    "height": 500
  }
}
```

除了 `xlsx`，也支持后缀为 `csv` 及 `tsv` 的文件

## 配置项

由于接口可能有变化，这里只列出少量配置项，后续补充

```schema: scope="body"
{
  "type": "office-viewer",
  "excelOptions": {
    "showSheetTabBar": false,
    "showFormulaBar": false
  },
  "src": "/examples/static/all.xlsx"
}
```

| 属性名          | 类型      | 默认值 | 说明                     |
| --------------- | --------- | ------ | ------------------------ |
| showFormulaBar  | `boolean` | true   | 是否显示公式拦           |
| showSheetTabBar | `boolean` | true   | 是否显示底部 sheet 切换  |
| fontURL         | `object`  |        | 字体地址，参考下面的说明 |

## 字体配置

由于浏览器中缺少特定字体，将展现会不一致，这些字体都是有版权的，因此本项目中不提供，需要自行准备，然后配置 `fontURL` 映射到对应的地址，渲染时就会加载。

类似如下配置

```json
{
  "type": "office-viewer",
  "excelOptions": {
    "fontURL": {
      "等线": "/static/font/DengXian.ttf",
      "仿宋": "/static/font/STFANGSO.TTF",
      "黑体": "/static/font/simhei.ttf"
    }
  },
  "src": "/examples/static/all.xlsx"
}
```

---

### Zh CN Components Office Viewer (`docs/zh-CN/components/office-viewer.md`)

---
title: Office Viewer
description:
type: 0
group: ⚙ 组件
menuName: OfficeViewer 文档渲染
icon:
order: 23
---

> 2.9.0 及以上版本

用于渲染 office 文档，目前只支持 docx 和 xlsx 格式，本文档只介绍 docx 的配置，xlsx 的配置请参考 [office-viewer-excel](office-viewer-excel)

## 基本用法

```schema: scope="body"
{
  "type": "office-viewer",
  "src": "/examples/static/simple.docx",
  "wordOptions": {
    "padding": "8px",
    "ignoreWidth": false
  }
}
```

## 渲染配置项

目前只支持 Word 文档，所以只有 word 的配置项，放在 `wordOptions` 下

Word 渲染支持以下功能：

- 基础文本样式
- 表格及表格样式
- 内嵌图片
- 列表
- 注音
- 链接
- 文本框
- 形状
- 数学公式（依赖 MathML，需要比较新的浏览器，或者试试 [polyfill](https://github.com/w3c/mathml-polyfills)）
- 分页渲染

不支持的功能：艺术字、域、对象、目录

### word 渲染配置属性表

```json
{
  "type": "office-viewer",
  "wordOptions": {
    "padding": "8px",
    "ignoreWidth": false
  }
}
```

| 属性名          | 类型      | 默认值        | 说明                                                       |
| --------------- | --------- | ------------- | ---------------------------------------------------------- |
| classPrefix     | `string`  | 'docx-viewer' | 渲染的 class 类前缀                                        |
| ignoreWidth     | `boolean` | false         | 忽略文档里的宽度设置，用于更好嵌入到页面里，但会减低还原度 |
| padding         | `string`  |               | 设置页面间距，忽略文档中的设置                             |
| bulletUseFont   | `boolean` | true          | 列表使用字体渲染，请参考下面的乱码说明                     |
| fontMapping     | `object`  |               | 字体映射，是个键值对，用于替换文档中的字体                 |
| forceLineHeight | `string`  |               | 设置段落行高，忽略文档中的设置                             |
| enableVar       | `boolean` | true          | 是否开启变量替换功能                                       |
| printOptions    | `object`  |               | 针对打印的特殊设置，可以覆盖其它所有设置项                 |

#### 分页渲染

> 2.10.0 及以上版本

默认情况下 word 文档渲染使用流式布局，这样能更好融入到已有页面中，但展现上会和原先的文档有较大差异，且不支持页眉页脚，如果希望能看起来更像桌面端的效果，可以通过 `page` 配置开启分页渲染

```schema: scope="body"
{
  "type": "office-viewer",
  "id": "office-viewer-page",
  "wordOptions": {
    "page": true
  },
  "src": "/examples/static/page.docx",
}
```

分页渲染的其它设置项

| 属性名             | 类型      | 默认值    | 说明                                       |
| ------------------ | --------- | --------- | ------------------------------------------ |
| page               | `boolean` | false     | 是否开启分页渲染                           |
| pageMarginBottom   | `number`  | 20        | 页面上下间距                               |
| pageBackground     | `string`  | '#FFF'    | 页面内背景色                               |
| pageShadow         | `boolean` | true      | 是否显示阴影                               |
| pageWrap           | `boolean` | true      | 是否显示页面包裹                           |
| pageWrapBackground | `string`  | '#ECECEC' | 页面包裹的背景色                           |
| zoom               | `number`  |           | 缩放比例，取值 0-1 之间                    |
| zoomFitWidth       | `boolean` | false     | 自适应宽度缩放，如果设置了 zoom 将不会生效 |

### 关于渲染效果差异

目前的实现难以保证和本地 Word 渲染完全一致，会遇到以下问题：

1. 字体大小不一致
1. 单元格宽度不一致，表格完全依赖浏览器渲染

如果追求完整效果打印，目前只能使用下载文件的方式用本地 Word 进行打印。

## 列表符号出现乱码问题

默认情况下列表左侧的符号使用字体渲染，这样能做到最接近 Word 渲染效果，但如果用户的系统中没有这些字体就会显示乱码，为了解决这个问题需要手动在 amis 渲染的页面里导入对应的字体，比如

```css
<style>
  @font-face {
    font-family: Wingdings;
    src: url(./static/font/wingding.ttf);
  }

  @font-face {
    font-family: Symbol;
    src: url(./static/font/symbol.ttf);
  }
</style>
```

目前已知会有 `Wingdings` 和 `Symbol` 两个字体，可能还有别的

如果不想嵌入这两个字体，就只能在前面的 `wordOptions` 里设置 `bulletUseFont: false`。

## 变量替换

文档可以预先定义变量，通过配置 `enableVar` 来开启这个功能，在实际渲染时根据上下文数据来渲染变量，比如

```schema: scope="body"
{
  "type": "form",
  "title": "",
  "mode": "inline",
  "wrapWithPanel": false,
  "body": [
    {
      "type": "input-text",
      "name": "name",
      "value": "amis",
      "label": "姓名"
    },
    {
      "type": "input-email",
      "name": "email",
      "label": "邮箱"
    },
    {
      "type": "input-text",
      "name": "phone",
      "label": "手机号"
    },
    {
      "type": "office-viewer",
      "id": "office-viewer",
      "src": "/examples/static/info.docx",
      "wordOptions": {
        "enableVar": true,
        "padding": "8px"
      }
    }
  ]
}
```

如果关闭将显示原始文档

```schema: scope="body"
{
  "type": "office-viewer",
  "id": "office-viewer",
  "src": "/examples/static/info.docx",
  "wordOptions": {
    "padding": "8px"
  }
}
```

### 变量说明

目前变量使用的写法是 `{{name}}`，其中 `name` 代表变量名，另外这里可以是 amis 表达式，比如前面示例的 `{{DATETOSTR(TODAY(), 'YYYY-MM-DD')}}`

**Word 经常会自作主张进行语法检查，生成无关的标签导致变量替换出错，解决办法是参考这个[文档](https://support.microsoft.com/zh-cn/office/%E5%9C%A8-word-%E4%B8%AD%E6%A3%80%E6%9F%A5%E8%AF%AD%E6%B3%95-%E6%8B%BC%E5%86%99%E7%AD%89-0f43bf32-ccde-40c5-b16a-c6a282c0d251?ui=zh-cn&rs=zh-cn&ad=cn)，将所有语法检查都忽略掉，也就是文档里不再有飘红的文字**

### 表格行循环

目前针对表格支持循环语法，下面例子中第一个是模板里的变量写法，循环以 `{{#xxx}}` 开头，`{{/}}` 结束（不过目前还不支持嵌套语法，所以这个结束符合可以省略）

```schema
{
  "type": "page",
  "body": [
    {
      "type": "office-viewer",
      "id": "office-viewer-table-list",
      "src": "/examples/static/table-list.docx",
      "wordOptions": {
        "padding": "8px"
      }
    },
    {
      "type": "service",
      "api": "/api/mock2/sample/mirror?json=%7B%22users%22%3A%5B%7B%22name%22%3A%22u1%22%2C%22age%22%3A10%2C%22img%22%3A%22https%3A%2F%2Fsuda.cdn.bcebos.com%2Fimages%2Famis%2Fai-fake-face.jpg%22%7D%2C%7B%22name%22%3A%22u2%22%2C%22age%22%3A11%7D%5D%7D",
      "body": [{
        "type": "office-viewer",
        "src": "/examples/static/table-list.docx",
        "wordOptions": {
          "padding": "8px",
          "enableVar": true,
          "ignoreWidth": true
        },
        "trackExpression": "${users}"
      }]
    },
    {
      "type": "action",
      "label": "下载文档",
      "onEvent": {
          "click": {
            "actions": [
              {
                "actionType": "saveAs",
                "componentId": "office-viewer-table-list"
              }
            ]
          }
        }
    },

  ]
}
```

循环的语法是以 `{{#name}}` 开始，`{{/}}` 结束，在这期间的变量会取循环内的值。

注意上面的例子用到了 `trackExpression`，默认情况下如果设置了 `enableVar`，每次上层数据变化都会重新渲染文档，如果文档较大可能会有性能问题，这时可以通过配置 `trackExpression` 来限制只有某个数据变化时才重新渲染。

### 图片中的变量

> 2.10 及以上版本

如果要将文档中的图片设置为变量，需要右键对应的图片，选择「查看可选文字」，然后填入类似 `{{img}}` 变量标识，在渲染时图片将替换为这个 `img` 变量的 url 地址



下面是示例

```schema: scope="body"
{
  "type": "form",
  "title": "",
  "wrapWithPanel": false,
  "body": [
    {
      "type": "input-text",
      "name": "img",
      "value": "https://suda.cdn.bcebos.com/amis/images/alice-macaw.jpg",
      "label": "图片地址"
    },
    {
      "type": "office-viewer",
      "id": "office-viewer",
      "src": "/examples/static/image-alt-var.docx",
      "wordOptions": {
        "enableVar": true,
        "padding": "8px"
      }
    }
  ]
}
```

## 不渲染模式

通过配置 `display: false` 可以让文档不渲染，虽然不渲染，但还是可以使用后面的下载及打印功能

## 下载文档

基于事件动作实现

```schema: scope="body"
[
  {
    "type": "action",
    "label": "下载文档",
    "onEvent": {
        "click": {
          "actions": [
            {
              "actionType": "saveAs",
              "componentId": "office-viewer-download"
            }
          ]
        }
      }
  },
  {
    "type": "office-viewer",
    "id": "office-viewer-download",
    "display": false,
    "src": "/examples/static/simple.docx"
  }
]
```

## 打印文档

基于事件动作实现

```schema: scope="body"
[
  {
    "type": "action",
    "label": "打印",
    "onEvent": {
        "click": {
          "actions": [
            {
              "actionType": "print",
              "componentId": "office-viewer-print"
            }
          ]
        }
      }
  },
  {
    "type": "office-viewer",
    "id": "office-viewer-print",
    "display": false,
    "src": "/examples/static/simple.docx"
  }
]
```

有个 `printOptions` 配置项可以用来自定义在打印时的配置，默认设置是：

```json
{
  "page": true,
  "pageWrap": false,
  "pageShadow": false,
  "pageMarginBottom": 0,
  "pageWrapPadding": undefined
}
```

## 配合文件上传实现预览功能

配置和 `input-file` 相同的 `name` 即可

```schema: scope="body"
{
  "type": "form",
  "title": "",
  "wrapWithPanel": false,
  "body": [
    {
      "type": "input-file",
      "name": "file",
      "label": "File",
      "asBlob": true,
      "accept": ".docx"
    },
    {
      "type": "office-viewer",
      "id": "office-viewer",
      "name": "file"
    }
  ]
}
```

## 是否显示 loading

通过 `"loading": true` 配置显示 loading，主要用于网络较慢的场景。

## 属性表

| 属性名      | 类型      | 默认值 | 说明                  |
| ----------- | --------- | ------ | --------------------- |
| src         | Api       |        | 文档地址              |
| loading     | `boolean` | false  | 是否显示 loading 图标 |
| enableVar   | `boolean` |        | 是否开启变量替换功能  |
| wordOptions | `object`  |        | Word 渲染配置         |

## 动作表

当前组件对外暴露以下特性动作，其他组件可以通过指定`actionType: 动作名称`、`componentId: 该组件id`来触发这些动作，动作配置可以通过`args: {动作配置项名称: xxx}`来配置具体的参数，详细请查看[事件动作](../../docs/concepts/event-action#触发其他组件的动作)。

| 动作名称 | 动作配置               | 说明     |
| -------- | ---------------------- | -------- |
| saveAs   | `name?: string` 文件名 | 下载文档 |
| print    | -                      | 打印文档 |

---

### Zh CN Components Page (`docs/zh-CN/components/page.md`)

---
title: Page 页面
description:
type: 0
group: ⚙ 组件
menuName: Page 页面
icon:
order: 23
---

Page 组件是 amis 页面 JSON 配置中顶级容器组件，是整个页面配置的入口组件。

## 基本用法

我们这里在内容区中简单渲染一段文字。

```schema
{
  "type": "page",
  "title": "标题",
  "body": "Hello World!"
}
```

## 渲染组件

内容区同样可以渲染各种组件，这里我们渲染一个表单。

```schema: scope="body"
{
    "type": "form",
    "api": "/api/mock2/form/saveForm",
    "body": [
      {
        "type": "input-text",
        "name": "name",
        "label": "姓名："
      }
    ]
}
```

## 在其他区域渲染组件

Page 默认将页面分为几个区域，分别是**内容区（`body`）**、**侧边栏（`aside`）** 和 **工具栏（`toolbar`）部分**，你可以在这些区域配置你想要的组件和内容。

```schema
{
  "type": "page",
  "aside": [
    {
      "type": "tpl",
      "tpl": "这是侧边栏部分"
    }
  ],
  "toolbar": [
    {
      "type": "tpl",
      "tpl": "这是工具栏部分"
    }
  ],
  "body": [
    {
      "type": "tpl",
      "tpl": "这是内容区"
    }
  ]
}
```

> 不同区域都是`Page`的子节点，也就是说都可以使用`Page`下数据作用域。

## 页面初始化请求

通过配置`initApi`，可以在初始化页面时请求所配置的接口。

```schema
{
  "type": "page",
  "initApi": "/api/mock2/page/initData",
  "body": [
    {
      "type": "tpl",
      "tpl": "当前时间是：${date}"
    }
  ]
}
```

具体 API 规范查看 [API 文档](../../docs/types/api)。

## 轮询初始化接口

想要在页面渲染后，轮询请求初始化接口，步骤如下：

1. 配置 initApi；
2. 配置 interval：单位为毫秒，最小 1000。

```schema
{
  "type": "page",
  "initApi": "/api/mock2/page/initData",
  "interval": 3000,
  "body": [
    {
      "type": "tpl",
      "tpl": "当前时间是：${date}"
    }
  ]
}
```

如果希望在满足某个条件的情况下停止轮询，配置`stopAutoRefreshWhen`表达式。

```schema
{
  "type": "page",
  "initApi": "/api/mock2/page/initData",
  "stopAutoRefreshWhen": "this.time % 5", // 当时间戳能被5整除时，停止轮询
  "interval": 3000,
  "body": [
    {
      "type": "tpl",
      "tpl": "当前时间戳是：${date}"
    }
  ]
}
```

## 下拉刷新

通过配置`pullRefresh`，可以设置下拉刷新功能（仅用于移动端）。

```schema
{
  "type": "page",
  "initApi": "/api/mock2/page/initData",
  "pullRefresh": {
    "disabled": false
  },
  "body": [
    {
      "type": "tpl",
      "tpl": "当前时间是：${date}"
    }
  ]
}
```

配置下拉刷新文案

```schema
{
  "type": "page",
  "initApi": "/api/mock2/page/initData",
  "pullRefresh": {
    "disabled": false,
    "pullingText": "继续下拉",
    "loosingText": "可以释放了"
  },
  "body": [
    {
      "type": "tpl",
      "tpl": "当前时间是：${date}"
    }
  ]
}
```

## CSS 变量

通过设置 CSS 变量几乎可以修改 amis 中任意组件的展现，具体细节请参考[样式](../../../style)。

```schema
{
  "type": "page",
  "cssVars": {
    "--text-color": "#108cee"
  },
  "body": {
    "type": "form",
    "body": [
      {
        "type": "input-text",
        "label": "文本框",
        "name": "text"
      }
    ]
  }
}
```

## 自定义 CSS

> 1.3.0 及以上版本

虽然 amis 提供了很多内置样式，但想要更精细控制样式，最好的方式依然是编写自定义 CSS，在之前的版本中需要外部页面配合，从 1.3.0 开始 amis 可以直接在配置中支持自定义 CSS

```schema
{
  "type": "page",
  "css": {
    ".myClass": {
      "color": "blue"
    }
  },
  "body": {
    "type": "tpl",
    "tpl": "文本",
    "className": "myClass"
  }
}
```

上面的配置会自动创建一个 `<style>` 标签，其中内容就是：

```css
.myClass {
  color: blue;
}
```

配置写法和编写普通 css 的体验是一致的，可以使用任意 css 选择符及属性。

## aside 可调整宽度

通过配置 `asideResizor`，可以让侧边栏支持动态调整宽度，同时可以通过 `asideMinWidth`、`asideMaxWidth` 设置 aside 最大最小宽度。

```schema
{
  "type": "page",
  "asideResizor": true,
  "asideMinWidth": 150,
  "asideMaxWidth": 400,
  "aside": [
    {
      "type": "tpl",
      "tpl": "这是侧边栏部分"
    }
  ],
  "body": [
    {
      "type": "tpl",
      "tpl": "这是内容区"
    }
  ]
}
```

## aside 位置固定

通过配置 `asideSticky` 来开关，默认是开启状态。

## aside 展示位置

通过配置 `asidePosition`，可以控制侧边栏的展示位置。

```schema
{
  "type": "page",
  "asideResizor": true,
  "asidePosition": "right",
  "aside": [
    {
      "type": "tpl",
      "tpl": "这是侧边栏部分"
    }
  ],
  "body": [
    {
      "type": "tpl",
      "tpl": "这是内容区"
    }
  ]
}
```

## 属性表

| 属性名              | 类型                                      | 默认值                                     | 说明                                                                                  |
| ------------------- | ----------------------------------------- | ------------------------------------------ | ------------------------------------------------------------------------------------- |
| type                | `string`                                  | `"page"`                                   | 指定为 Page 组件                                                                      |
| title               | [SchemaNode](../../docs/types/schemanode) |                                            | 页面标题                                                                              |
| subTitle            | [SchemaNode](../../docs/types/schemanode) |                                            | 页面副标题                                                                            |
| remark              | [Remark](./remark)                        |                                            | 标题附近会出现一个提示图标，鼠标放上去会提示该内容。                                  |
| aside               | [SchemaNode](../../docs/types/schemanode) |                                            | 往页面的边栏区域加内容                                                                |
| asideResizor        | `boolean`                                 |                                            | 页面的边栏区域宽度是否可调整                                                          |
| asideMinWidth       | `number`                                  |                                            | 页面边栏区域的最小宽度                                                                |
| asideMaxWidth       | `number`                                  |                                            | 页面边栏区域的最大宽度                                                                |
| asideSticky         | `boolean`                                 | true                                       | 用来控制边栏固定与否                                                                  |
| asidePosition       | `"left" \| "right"`                       | `"left"`                                   | 页面边栏区域的位置                                                                    |
| toolbar             | [SchemaNode](../../docs/types/schemanode) |                                            | 往页面的右上角加内容，需要注意的是，当有 title 时，该区域在右上角，没有时该区域在顶部 |
| body                | [SchemaNode](../../docs/types/schemanode) |                                            | 往页面的内容区域加内容                                                                |
| className           | `string`                                  |                                            | 外层 dom 类名                                                                         |
| cssVars             | `object`                                  |                                            | 自定义 CSS 变量，请参考[样式](../style)                                               |
| toolbarClassName    | `string`                                  | `v-middle wrapper text-right bg-light b-b` | Toolbar dom 类名                                                                      |
| bodyClassName       | `string`                                  | `wrapper`                                  | Body dom 类名                                                                         |
| asideClassName      | `string`                                  | `w page-aside-region bg-auto`              | Aside dom 类名                                                                        |
| headerClassName     | `string`                                  | `bg-light b-b wrapper`                     | Header 区域 dom 类名                                                                  |
| initApi             | [API](../../docs/types/api)               |                                            | Page 用来获取初始数据的 api。返回的数据可以整个 page 级别使用。                       |
| initFetch           | `boolean`                                 | `true`                                     | 是否起始拉取 initApi                                                                  |
| initFetchOn         | [表达式](../../docs/concepts/expression)  |                                            | 是否起始拉取 initApi, 通过表达式配置                                                  |
| interval            | `number`                                  | `3000`                                     | 刷新时间(最小 1000)                                                                   |
| silentPolling       | `boolean`                                 | `false`                                    | 配置刷新时是否显示加载动画                                                            |
| stopAutoRefreshWhen | [表达式](../../docs/concepts/expression)  | `""`                                       | 通过表达式来配置停止刷新的条件                                                        |
| pullRefresh         | `object`                                  | `{disabled: true}`                         | 下拉刷新配置（仅用于移动端）                                                          |

## 事件表

当前组件会对外派发以下事件，可以通过`onEvent`来监听这些事件，并通过`actions`来配置执行的动作，在`actions`中可以通过`${事件参数名}`或`${event.data.[事件参数名]}`来获取事件产生的数据，详细请查看[事件动作](../../docs/concepts/event-action)。

> `[name]`为当前数据域中的字段名，例如：当前数据域为 {username: 'amis'}，则可以通过${username}获取对应的值。

| 事件名称    | 事件参数                                                                                                                                                                                   | 说明                                                |
| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------- |
| init        | -                                                                                                                                                                                          | 组件实例被创建并插入 DOM 中时触发。2.4.1 及以上版本 |
| inited      | `responseData: any` 请求的响应数据</br>`responseStatus: number` 响应状态，0 表示成功</br>`responseMsg: string`响应消息, `error`表示接口是否成功<br/>`[name]: any` 当前数据域中指定字段的值 | initApi 接口请求完成时触发                          |
| pullRefresh | -                                                                                                                                                                                          | 开启下拉刷新后，下拉释放后触发（仅用于移动端）      |

### init 和 inited

```schema
{
  "type": "page",
  "initApi": "/api/mock2/page/initData",
  "body": [
    {
      "type": "tpl",
      "tpl": "当前时间是：${date}"
    }
  ],
  "onEvent": {
    "init": {
      "actions": [
        {
          "actionType": "toast",
          "args": {
            "msgType": "info",
            "msg": "init"
          }
        }
      ]
    },
    "inited": {
      "actions": [
        {
          "actionType": "toast",
          "args": {
            "msgType": "info",
            "msg": "${event.data.responseData|json}"
          }
        }
      ]
    }
  }
}
```

## 动作表

当前组件对外暴露以下特性动作，其他组件可以通过指定`actionType: 动作名称`、`componentId: 该组件id`来触发这些动作，动作配置可以通过`args: {动作配置项名称: xxx}`来配置具体的参数，详细请查看[事件动作](../../docs/concepts/event-action#触发其他组件的动作)。

| 动作名称 | 动作配置                   | 说明                                     |
| -------- | -------------------------- | ---------------------------------------- |
| reload   | -                          | 重新加载，调用 `intiApi`，刷新数据域数据 |
| setValue | `value: object` 更新的数据 | 更新数据                                 |

### reload

#### 只做刷新

重新发送`initApi`请求，刷新 Page 时，只配置`componentId`目标组件 ID 即可。

```schema
{
  "type": "page",
  "id": "page_reload_1",
  "initApi": "/api/mock2/page/initData",
  "body": [
    {
      "type": "button",
      "label": "刷新Page数据加载请求",
      "className": "mb-2",
      "onEvent": {
        "click": {
          "actions": [
            {
              "componentId": "page_reload_1",
              "actionType": "reload"
            }
          ]
        }
      }
    },
    {
      "type": "tpl",
      "tpl": "当前时间是：${date}"
    }
  ]
}
```

#### 发送数据并刷新

刷新 Page 组件时，如果配置了`data`，将先发送`data`给目标组件，并将该数据合并到目标组件的数据域中（如果配置`"dataMergeMode": "override"`将覆盖目标组件的数据），然后重新请求数据。

```schema
{
  "type": "page",
  "id": "page_reload_2",
  "initApi": "/api/mock2/page/initData",
  "body": [
    {
      "type": "button",
      "label": "刷新Page数据加载请求，并将我的年龄设置为18",
      "className": "mb-2",
      "onEvent": {
        "click": {
          "actions": [
            {
              "componentId": "page_reload_2",
              "actionType": "reload",
              "data": {
                "age": 18
              }
            }
          ]
        }
      }
    },
    {
      "type": "tpl",
      "tpl": "当前时间是：${date}， 我的年龄：${age|default:'-'}"
    }
  ]
}
```

### setValue

通过`setValue`更新指定页面组件的数据。

#### 合并数据

默认`setValue`会将新数据与目标组件数据进行合并。

```schema
{
  "type": "page",
  "id": "page02",
  "initApi": "/api/mock2/page/initData",
  "body": [
    {
      "type": "button",
      "label": "更新数据",
      "className": "mb-2",
      "onEvent": {
        "click": {
          "actions": [
            {
              "componentId": "page02",
              "actionType": "setValue",
              "args": {
                "value": {"date": "2023-05-01"}
              }
            }
          ]
        }
      }
    },
    {
      "type": "tpl",
      "tpl": "标题：${title} 当前时间是：${date}"
    }
  ]
}
```

#### 覆盖数据

可以通过`"dataMergeMode": "override"`来覆盖目标组件数据。

```schema
{
  "type": "page",
  "id": "page02",
  "initApi": "/api/mock2/page/initData",
  "body": [
    {
      "type": "button",
      "label": "更新数据",
      "className": "mb-2",
      "onEvent": {
        "click": {
          "actions": [
            {
              "componentId": "page02",
              "actionType": "setValue",
              "args": {
                "value": {"date": "2023-05-01"}
              },
              "dataMergeMode": "override"
            }
          ]
        }
      }
    },
    {
      "type": "tpl",
      "tpl": "标题：${title|default:'-'} 当前时间是：${date}"
    }
  ]
}
```

---

### Zh CN Components Pagination Wrapper (`docs/zh-CN/components/pagination-wrapper.md`)

---
title: PaginationWrapper 分页容器
description:
type: 0
group: ⚙ 组件
menuName: PaginationWrapper
icon:
order: 59
---

分页容器组件，可以用来对已有列表数据做分页处理。

- 输入：默认读取作用域中的 items 变量，如果是其他变量名请配置 `inputName`。
- 输出：经过分页处理后会把分页后的数据下发给 `outputName` （默认也是 items）对应的数据。

```schema: scope="body"
{
    "type": "service",
    "api": "/api/mock2/crud/table",
    "body": [
        {
            "type": "pagination-wrapper",
            "inputName": "rows",
            "outputName": "rows",
            "perPage": 2,
            "body": [
                {
                    "type": "table",
                    "title": "分页表格",
                    "source": "${rows}",
                    "columns": [
                        {
                            "name": "engine",
                            "label": "Engine"
                        },
                        {
                            "name": "version",
                            "label": "Version"
                        }
                    ]
                }
            ]
        }
    ]
}
```

## 属性表

| 属性名        | 类型                                      | 默认值                 | 说明                                                                               |
| ------------- | ----------------------------------------- | ---------------------- | ---------------------------------------------------------------------------------- |
| type          | `string`                                  | `"pagination-wrapper"` | 指定为 Pagination-Wrapper 渲染器                                                   |
| showPageInput | `boolean`                                 | `false`                | 是否显示快速跳转输入框                                                             |
| maxButtons    | `number`                                  | `5`                    | 最多显示多少个分页按钮                                                             |
| inputName     | `string`                                  | `"items"`              | 输入字段名                                                                         |
| outputName    | `string`                                  | `"items"`              | 输出字段名                                                                         |
| perPage       | `number`                                  | `10`                   | 每页显示多条数据                                                                   |
| position      | `'top'` 或 `'bottom'` 或 `'none'`         | `"top"`                | 分页显示位置，如果配置为 none 则需要自己在内容区域配置 pagination 组件，否则不显示 |
| body          | [SchemaNode](../../docs/types/schemanode) |                        | 内容区域                                                                           |

---

### Zh CN Components Pagination (`docs/zh-CN/components/pagination.md`)

---
title: Pagination 分页组件
description:
type: 0
group: ⚙ 组件
menuName: Pagination
icon:
order: 73
---

## 基本用法

```schema: scope="body"
{
    "type": "service",
    "api": "/api/mock2/crud/table",
    "body": [
        {
            "type": "pagination",
            "layout": "total,perPage,pager,go",
            "mode": "normal",
            "activePage": 2,
            "lastPage": 99999,
            "total": 999,
            "perPage": 10,
            "maxButtons": 7,
            "showPerPage": true,
            "perPageAvailable": [10, 20, 50, 100],
            "showPageInput": true,
            "disabled": false
        }
    ]
}
```

## 微型模式

> `6.0.0`及以上版本

配置`"size": "sm"`可实现微型模式


```schema: scope="body"
{
    "type": "service",
    "api": "/api/mock2/crud/table",
    "body": [
        {
            "type": "pagination",
            "layout": "total,perPage,pager,go",
            "mode": "normal",
            "activePage": 1,
            "lastPage": 99999,
            "size": "sm",
            "total": 999,
            "perPage": 10,
            "maxButtons": 7,
            "showPerPage": true,
            "perPageAvailable": [10, 20, 50, 100],
            "showPageInput": true,
            "disabled": false

        }
    ]
}
```

## 简洁模式

配置`"mode": "simple"`可实现简洁模式，支持input框输入指定页码跳转，input框中也可以通过键盘上下键进行页码跳转

```schema: scope="body"
{
    "type": "service",
    "api": "/api/mock2/crud/table",
    "body": [
        {
            "type": "pagination",
            "mode": "simple",
            "activePage": 2,
            "hasNext": true
        }
    ]
}
```

## 属性表

| 属性名           | 类型                       | 默认值                                   | 说明                                                      | 版本 |
| ---------------- | -------------------------- | ---------------------------------------- | --------------------------------------------------------- | --- |
| type             | `string`                   | `"pagination"`                           | 指定为 Pagination 渲染器                                  |
| mode             | `normal` \| `simple`       | `normal`                                 | 迷你版本/简易版本 只显示左右箭头，配合 hasNext 使用       |
| layout           | `string` \| `string[]`     | `["pager"]`                              | 通过控制 layout 属性的顺序，调整分页结构布局              |
| maxButtons       | `number` \| `string`       | `5`                                      | 最多显示多少个分页按钮，最小为 5                          |
| total            | `number` \| `string`       |                                          | 总条数                                                    |
| activePage       | `number` \| `string`       | `1`                                      | 当前页数                                                  |
| perPage          | `number` \| `string`       | `10`                                     | 每页显示多条数据                                          |
| showPerPage      | `boolean`                  | false                                    | 是否展示 perPage 切换器 layout 和 showPerPage 都可以控制  |
| size      | `'sm' \| 'md'`               | `md`                                    | 组件尺寸，支持`md`、`sm`设置  |`6.0.0`后支持变量
| ellipsisPageGap      | `number` \| `string`                 | 5                                    | 多页跳转页数，页数较多出现`...`时点击省略号时每次前进/后退的页数，默认为5  | `6.0.0`后支持变量
| perPageAvailable | `number[]`                 | `[10, 20, 50, 100]`                      | 指定每页可以显示多少条                                    |
| showPageInput    | `boolean`                  | false                                    | 是否显示快速跳转输入框 layout 和 showPageInput 都可以控制 |
| disabled         | `boolean`                  | false                                    | 是否禁用                                                  |
| onPageChange     | page、perPage 改变时会触发 | (page: number, perPage: number) => void; | 分页改变触发                                              |

## 事件表

当前组件会对外派发以下事件，可以通过`onEvent`来监听这些事件，并通过`actions`来配置执行的动作，在`actions`中可以通过`${事件参数名}`或`${event.data.[事件参数名]}`来获取事件产生的数据，详细请查看[事件动作](../../docs/concepts/event-action)。

> `[name]`表示当前组件绑定的名称，即`name`属性，如果没有配置`name`属性，则通过`value`取值。
> | 事件名称 | 事件参数 | 说明 |
> | -------- | ------------------------------------- | ------------------------------------------- |
> | change | `page: number` 当前页码的值<br/>`perPage: number` 每页显示的记录数 | 当前页码值改变时触发 |

### change

切换页码时，通过更新 service 数据域中的 page 来实现联动刷新 table 表格数据。

```schema: scope="body"
{
    "type": "service",
    "id": "service_01",
    "api": "/api/mock2/crud/table?page=${page}",
    "data": {
        "page": 1
    },
    "body": [
        {
        "type": "table",
        "title": "表格1",
        "source": "$rows",
        "columns": [
          {
            "name": "engine",
            "label": "Engine"
          },
          {
            "name": "version",
            "label": "Version"
          }
        ]
      },
        {
            "type": "pagination",
            "activePage": "${page}",
            "hasNext": true,
            "onEvent": {
                "change": {
                    "actions": [
                        {
                            "actionType": "setValue",
                            "componentId": "service_01",
                            "args": {
                                "value": {
                                    "page": "${event.data.page}"
                                }
                            }
                        }
                    ]
                }
            }
        }
    ]
}
```

切换页码时，通过向 service 发送 page 并重新加载 service 数据来实现联动刷新 table 表格数据。

```schema: scope="body"
{
    "type": "service",
    "id": "service_02",
    "api": "/api/mock2/crud/table?page=${page}",
    "data": {
        "page": 1
    },
    "body": [
        {
        "type": "table",
        "title": "表格1",
        "source": "$rows",
        "columns": [
          {
            "name": "engine",
            "label": "Engine"
          },
          {
            "name": "version",
            "label": "Version"
          }
        ]
      },
        {
            "type": "pagination",
            "activePage": "${page}",
            "hasNext": true,
            "onEvent": {
                "change": {
                    "actions": [
                        {
                            "actionType": "reload",
                            "componentId": "service_02",
                            "data": {
                                "page": "${event.data.page}"
                            }
                        }
                    ]
                }
            }
        }
    ]
}
```

---

### Zh CN Components Panel (`docs/zh-CN/components/panel.md`)

---
title: Panel 面板
description:
type: 0
group: ⚙ 组件
menuName: Panel
icon:
order: 59
---

可以把相关信息以面板的形式展示到一块。

## 基本用法

```schema: scope="body"
{
    "type": "panel",
    "title": "面板标题",
    "body": "面板内容"
}
```

## 底部配置按钮

可以通过配置`actions`数组，实现渲染底部按钮栏

```schema: scope="body"
{
  "type": "panel",
  "title": "面板标题",
  "body": "面板内容",
  "actions": [
    {
      "type": "button",
      "label": "按钮 1",
      "actionType": "dialog",
      "dialog": {
        "title": "提示",
        "body": "对，你刚点击了！"
      }
    },

    {
      "type": "button",
      "label": "按钮 2",
      "actionType": "dialog",
      "dialog": {
        "title": "提示",
        "body": "对，你刚点击了！"
      }
    }
  ]
}
```

## 固定底部

有时 panel 内，内容过多，导致底部操作按钮不是很方便，可以配置`"affixFooter": true`，将底部部分贴在浏览器底部展示。

```schema: scope="body"
{
  "type": "panel",
  "title": "面板标题",
  "body": "面板内容",
  "affixFooter": true,
  "actions": [
    {
      "type": "button",
      "label": "按钮 1",
      "actionType": "dialog",
      "dialog": {
        "title": "提示",
        "body": "对，你刚点击了！"
      }
    },

    {
      "type": "button",
      "label": "按钮 2",
      "actionType": "dialog",
      "dialog": {
        "title": "提示",
        "body": "对，你刚点击了！"
      }
    }
  ]
}
```

## 属性表

| 属性名           | 类型                                      | 默认值                                 | 说明                |
| ---------------- | ----------------------------------------- | -------------------------------------- | ------------------- |
| type             | `string`                                  | `"panel"`                              | 指定为 Panel 渲染器 |
| className        | `string`                                  | `"panel-default"`                      | 外层 Dom 的类名     |
| headerClassName  | `string`                                  | `"panel-heading"`                      | header 区域的类名   |
| footerClassName  | `string`                                  | `"panel-footer bg-light lter wrapper"` | footer 区域的类名   |
| actionsClassName | `string`                                  | `"panel-footer"`                       | actions 区域的类名  |
| bodyClassName    | `string`                                  | `"panel-body"`                         | body 区域的类名     |
| title            | [SchemaNode](../../docs/types/schemanode) |                                        | 标题                |
| header           | [SchemaNode](../../docs/types/schemanode) |                                        | 头部容器            |
| body             | [SchemaNode](../../docs/types/schemanode) |                                        | 内容容器            |
| footer           | [SchemaNode](../../docs/types/schemanode) |                                        | 底部容器            |
| affixFooter      | `boolean`                                 |                                        | 是否固定底部容器    |
| actions          | Array<[Action](./action)>                 |                                        | 按钮区域            |

---

### Zh CN Components Pdf Viewer (`docs/zh-CN/components/pdf-viewer.md`)

---
title: PDF Viewer
description:
type: 0
group: ⚙ 组件
menuName: PDFViewer 渲染
icon:
order: 24
---

## 基本用法

```schema: scope="body"
{
  "type": "pdf-viewer",
  "id": "pdf-viewer",
  "src": "/examples/static/simple.pdf",
  "width": 500
}
```

## 配合文件上传实现预览功能

配置和 `input-file` 相同的 `name` 即可

```schema: scope="body"
{
  "type": "form",
  "title": "",
  "wrapWithPanel": false,
  "body": [
    {
      "type": "input-file",
      "name": "file",
      "label": "File",
      "asBlob": true,
      "accept": ".pdf"
    },
    {
      "type": "pdf-viewer",
      "id": "pdf-viewer",
      "name": "file",
      "width": 500
    }
  ]
}
```

## 属性表

| 属性名     | 类型   | 默认值 | 说明       |
| ---------- | ------ | ------ | ---------- |
| src        | Api    |        | 文档地址   |
| width      | number |        | 宽度       |
| height     | number | -      | 高度       |
| background | string | #fff   | PDF 背景色 |

---

### Zh CN Components Popover (`docs/zh-CN/components/popover.md`)

---
title: PopOver 弹出提示
description:
type: 0
group: ⚙ 功能
menuName: popover
icon:
order: 60
---

popover 不是一个独立组件，它是嵌入到其它组件中使用的，目前可以在以下组件中配置

- table 的 column
- list 的 column
- static
- cards 里的字段

## 基本配置

比如在 CRUD 的 tpl 中，可以默认截断显示，然后加上 popOver 来显示全部内容

```schema: scope="body"
{
    "type": "crud",
    "api": "/api/mock2/sample?waitSeconds=1",
    "columns": [
        {
            "type": "tpl",
            "name": "engine",
            "label": "Rendering engine",
            "tpl": "${engine|truncate:6}",
            "popOver": "${engine}"
        }
    ]
}
```

> 上面的 popOver 精简写法只支持 1.6.5 及以上版本，之前版本需要使用 "popOver": {"body": "$engine"}

## 在其它组件里的示例

```schema: scope="body"
[
  {
    "type": "form",
    "body": [
      {
        "name": "static",
        "type": "static",
        "label": "静态展示",
        "value": "static",
        "popOver": "弹出内容"
      }
    ]
  },
  {
    "type": "service",
    "api": "/api/mock2/sample?perPage=5",
    "body": [
      {
        "type": "list",
        "source": "$rows",
        "listItem": {
          "body": [
            {
              "type": "hbox",
              "columns": [
                {
                  "label": "Engine",
                  "name": "engine",
                  "popOver": "弹出内容"
                }
              ]
            }
          ]
        }
      }
    ]
  },
  {
    "type": "service",
    "api": "/api/mock2/sample?perPage=5",
    "body": {
      "type": "cards",
      "source": "$rows",
      "card": {
        "body": [
          {
            "label": "Engine",
            "name": "engine",
            "popOver": "弹出内容"
          }
        ]
      }
    }
  }
]
```

## 更多配置

可以配置触发条件，是否显示 icon，title 等，具体请参考后面的配置列表

```schema: scope="body"
{
    "type": "crud",
    "api": "/api/mock2/sample?waitSeconds=1",
    "columns": [
        {
            "type": "tpl",
            "name": "engine",
            "label": "Rendering engine",
            "tpl": "${engine|truncate:6}",
            "popOver": {
                "trigger": "hover",
                "position": "left-top",
                "showIcon": false,
                "title": "标题",
                "body": {
                    "type": "tpl",
                    "tpl": "${engine}"
                }
            }
        }
    ]
}
```

## popOverEnableOn

可以给列上配置`popOverEnableOn`属性，该属性为[表达式](../../docs/concepts/expression)，通过[表达式](../../docs/concepts/expression)配置当前行是否启动`popOver`功能

```schema: scope="body"
{
    "type": "crud",
    "api": "/api/mock2/sample?waitSeconds=1",
    "columns": [
        {
            "name": "id",
            "label": "ID",
            "popOver": {
                "body": {
                    "type": "tpl",
                    "tpl": "${id}"
                }
            },
            "popOverEnableOn": "this.id == 1"
        },
        {
            "name": "engine",
            "label": "Rendering engine",
            "popOver": {
                "body": {
                    "type": "tpl",
                    "tpl": "${engine}"
                }
            }
        }
    ]
}
```

## 属性列表

- `mode` 可配置成 `popOver`、`dialog` 或者 `drawer`。 默认为 `popOver`。
- `size` 当配置成 `dialog` 或者 `drawer` 的时候有用。
- `position` 配置弹出位置，只有 `popOver` 模式有用，默认是自适应。
  可选参数：

  - `center`
  - `left-top`
  - `right-top`
  - `left-bottom`
  - `right-bottom`

  atX-atY-myX-myY
  即：对齐目标的位置-对齐自己的位置

  - `left-top-right-bottom` 在目标位置的左上角显示。
  - `left-center-right-center` 在目标的左侧显示，垂直对齐。
  - ...

  固定位置

  - `fixed-center`
  - `fixed-left-top`
  - `fixed-right-top`
  - `fixed-left-bottom`
  - `fixed-right-bottom`。

- `offset` 默认 `{top: 0, left: 0}`，如果要来一定的偏移请设置这个。
- `trigger` 触发弹出的条件。可配置为 `click` 或者 `hover`。默认为 `click`。
- `showIcon` 是否显示图标。默认会有个放大形状的图标出现在列里面。如果配置成 false，则触发事件出现在列上就会触发弹出。
- `title` 弹出框的标题。
- `body` 弹出框的内容。

---

### Zh CN Components Portlet (`docs/zh-CN/components/portlet.md`)

---
title: Portlet 门户栏目
description:
type: 0
group: ⚙ 组件
menuName: Portlet
icon:
order: 60
---

门户栏目组件。

## 基本用法

```schema
{
    "type": "page",
    "data": {
        "text": "这是一段描述信息"
    },
    "body": {
        "type": "portlet",
        "description": "${text}",
        "tabs": [
            {
                "title": "标题",
                "tab": "Content 1"
            },
            {
                "title": "标题2",
                "tab": "Content 2"
            }
        ]
    }
}
```

## 配置工具栏

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 隐藏头部

去掉头部，默认只展示内容 tab 第一项的内容

```schema: scope="body"
{
    "type": "portlet",
    "hideHeader": true,
    "tabs": [
        {
            "title": "Tab 1",
            "tab": "Content 1"
        }
    ]
}
```

## 设置 style

默认 tabs 只有一项的时候没有选中状态

```schema: scope="body"
{
    "type": "portlet",
    "style": {
        "borderColor": '#333'
    },
    "tabs": [
        {
            "title": "Tab 1",
            "tab": "Content 1"
        }
    ]
}
```

## 去掉分隔线

```schema: scope="body"
{
    "type": "portlet",
    "divider": false,
    "tabs": [
        {
            "title": "标题",
            "tab": "Content 1"
        }
    ]
}
```

## source 动态数据

配置 source 属性,根据某个数据来动态生成。具体使用参考 Tabs 选项卡组件

## 图标

通过 icon 可以设置 tab 的图标，可以是 fontawesome 或 URL 地址。

```schema: scope="body"
{
    "type": "portlet",
    "tabs": [
        {
            "title": "Tab 1",
            "tab": "Content 1",
            "icon": "https://suda.cdn.bcebos.com/images%2F2021-01%2Fdiamond.svg"
        },

        {
            "title": "Tab 2",
            "tab": "Content 2"
        }
    ]
}
```

## mountOnEnter

只有在点击卡片的时候才会渲染，在内容较多的时候可以提升性能，但第一次点击的时候会有卡顿。

## unmountOnExit

如果你想在切换 tab 时，自动销毁掉隐藏的 tab，请配置`"unmountOnExit": true`。

## 监听切换事件

```schema: scope="body"
{
    "type": "portlet",
    "activeKey": 1,
    "onSelect": "alert(key)",
    "tabs": [
      {
        "title": "Tab 1",
        "tab": "Content 1"
      },
      {
        "title": "Tab 2",
        "tab": "Content 2"
      }
    ]
  }
```

会传递 key 参数和 props

## 属性表

| 属性名                | 类型                                 | 默认值                              | 说明                                                                                       |
| --------------------- | ------------------------------------ | ----------------------------------- | ------------------------------------------------------------------------------------------ |
| type                  | `string`                             | `"portlet"`                         | 指定为 Portlet 渲染器                                                                      |
| className             | `string`                             |                                     | 外层 Dom 的类名                                                                            |
| tabsClassName         | `string`                             |                                     | Tabs Dom 的类名                                                                            |
| contentClassName      | `string`                             |                                     | Tabs content Dom 的类名                                                                    |
| tabs                  | `Array`                              |                                     | tabs 内容                                                                                  |
| source                | `Object`                             |                                     | tabs 关联数据，关联后可以重复生成选项卡                                                    |
| toolbar               | [SchemaNode](../types/schemanode)    |                                     | tabs 中的工具栏，不随 tab 切换而变化                                                       |
| style                 | `string \| Object`                   |                                     | 自定义样式                                                                                 |
| description           | [模板](../../docs/concepts/template) |                                     | 标题右侧信息                                                                               |
| hideHeader            | `boolean`                            | false                               | 隐藏头部                                                                                   |
| divider               | `boolean`                            | false                               | 去掉分隔线                                                                                 |
| tabs[x].title         | `string`                             |                                     | Tab 标题                                                                                   |
| tabs[x].icon          | `icon`                               |                                     | Tab 的图标                                                                                 |
| tabs[x].tab           | [SchemaNode](../types/schemanode)    |                                     | 内容区                                                                                     |
| tabs[x].toolbar       | [SchemaNode](../types/schemanode)    |                                     | tabs 中的工具栏，随 tab 切换而变化                                                         |
| tabs[x].reload        | `boolean`                            |                                     | 设置以后内容每次都会重新渲染，对于 crud 的重新拉取很有用                                   |
| tabs[x].unmountOnExit | `boolean`                            |                                     | 每次退出都会销毁当前 tab 栏内容                                                            |
| tabs[x].className     | `string`                             | `"bg-white b-l b-r b-b wrapper-md"` | Tab 区域样式                                                                               |
| mountOnEnter          | `boolean`                            | false                               | 只有在点中 tab 的时候才渲染                                                                |
| unmountOnExit         | `boolean`                            | false                               | 切换 tab 的时候销毁                                                                        |
| scrollable            | `boolean`                            | false                               | 是否导航支持内容溢出滚动，`vertical`和`chrome`模式下不支持该属性；`chrome`模式默认压缩标签 |

---

### Zh CN Components Progress (`docs/zh-CN/components/progress.md`)

---
title: Progress 进度条
description:
type: 0
group: ⚙ 组件
menuName: Progress 进度条
icon:
order: 60
---

## 基本用法

```schema
{
    "type": "page",
    "body": {
        "type": "progress",
        "value": 60
    }
}
```

## 颜色映射

可以配置`map`为单独颜色，例如：`#F96D3E`

若配置为字符串数组，指定颜色映射，例如，默认的 map 配置为：`['bg-danger', 'bg-warning', 'bg-info', 'bg-success', 'bg-success']`

它意味着将进度条分成了 5 份，`前20%`将会添加`bg-danger` css 类名到进度条上，`20%~40%`，将会添加`bg-warning`，以此类推，你可以自定义`map`来配置想要的进度效果

若配置为`[{value: 30, color: "#007bff"}, {value: 60, color: "#F96D3E"}]`, 表示为 value 小于等于`30`的区间显示`#007bff`, 大于`30`则显示`#F96D3E`

```schema
{
    "type": "page",
    "body": [
        {
            "type": "progress",
            "value": 40,
            "map": "#F96D3E"
        },
        {
            "type": "divider"
        },
        {
            "type": "progress",
            "value": 60,
            "map": ["bg-danger", "bg-success"]
        },
        {
            "type": "divider"
        },
        {
            "type": "progress",
            "value": 20,
            "map": [{
                value: 30,
                color: "#007bff"
            },
            {
                value: 60,
                color: "#fad733"
            }],
            "mode": "circle"
        },
        {
            "type": "divider"
        },
        {
            "type": "progress",
            "value": 50,
            "map": [{
                value: 50,
                color: "#007bff"
            },
            {
                value: 60,
                color: "#fad733"
            }],
            "mode": "circle"
        }
    ]
}
```

## 阈值（刻度）

```schema
{
    "type": "page",
    "body": {
        "type": "progress",
        "value": 60,
        "threshold": [
            {
                "value": "30%",
                "color": "red"
            },
            {
                "value": "90%",
                "color": "blue"
            }
        ],
        "showThresholdText": true
    }
}
```

## 用作 Field 时

当用在 Table 的列配置 Column、List 的内容、Card 卡片的内容和表单的 Static-XXX 中时，可以设置`name`属性，映射同名变量

### Table 中的列类型

```schema: scope="body"
{
    "type": "table",
    "data": {
        "items": [
            {
                "id": "1",
                "progress": 20
            },
            {
                "id": "2",
                "progress": 40
            },
            {
                "id": "3",
                "progress": 60
            }
        ]
    },
    "columns": [
        {
            "name": "id",
            "label": "Id"
        },

        {
            "name": "progress",
            "label": "进度",
            "type": "progress"
        }
    ]
}
```

List 的内容、Card 卡片的内容配置同上

### Form 中静态展示

```schema: scope="body"
{
    "type": "form",
    "data": {
        "progress": 60
    },
    "body": [
        {
            "type": "static-progress",
            "name": "progress",
            "label": "进度"
        }
    ]
}
```

## 显示背景间隔

```schema
{
    "type": "page",
    "body": {
        "type": "progress",
        "stripe": true,
        "value": 60
    }
}
```

## 显示动画

需要条形进度条才生效

```schema
{
    "type": "page",
    "body": [
      {
          "type": "progress",
          "animate": true,
          "value": 60
      },
      {
          "type": "divider"
      },
      {
          "type": "progress",
          "animate": true,
          "value": 60,
          "stripe": true
      }
    ]
}
```

## 圆形进度条

```schema
{
    "type": "page",
    "body": {
        "type": "progress",
        "value": 60,
        "mode": "circle"
    }
}
```

## 仪表盘进度条

可设置缺口位置和缺口角度

```schema
{
    "type": "page",
    "body": {
        "type": "progress",
        "value": 60,
        "mode": "dashboard",
        "gapDegree": 22,
        "gapPosition": "bottom"
    }
}
```

## 设置线条宽度

可设置 strokeWidth 调整线条宽度

```schema
{
    "type": "page",
    "body": [
        {
            "type": "progress",
            "value": 60,
            "mode": "line",
            "strokeWidth": 4
        },
        {
            "type": "progress",
            "value": 60,
            "mode": "line",
            "strokeWidth": 8
        },
        {
            "type": "progress",
            "value": 60,
            "mode": "line",
            "strokeWidth": 12
        },
        {
            "type": "progress",
            "value": 60,
            "mode": "dashboard",
            "strokeWidth": 4
        },
        {
            "type": "progress",
            "value": 60,
            "mode": "dashboard",
            "strokeWidth": 8
        },
        {
            "type": "progress",
            "value": 60,
            "mode": "dashboard",
            "strokeWidth": 12
        },
    ]
}
```

## 自定义格式输出内容

```schema
{
    "type": "page",
    "body": {
        "type": "progress",
        "mode": "circle",
        "value": 60,
        "valueTpl": "${value}个"
    }
}
```

## 属性表

| 属性名            | 类型                                                                                                                                                                                          | 默认值                                                               | 说明                                              |
| ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- | ------------------------------------------------- |
| type              | `string`                                                                                                                                                                                      |                                                                      | 如果在 Form 中用作静态展示，为`"static-progress"` |
| mode              | `string`                                                                                                                                                                                      | `line`                                                               | 进度「条」的类型，可选`line circle dashboard`     |
| className         | `string`                                                                                                                                                                                      |                                                                      | 外层 CSS 类名                                     |
| value             | [模板](../../docs/concepts/template)                                                                                                                                                          |                                                                      | 进度值                                            |
| placeholder       | `string`                                                                                                                                                                                      | `-`                                                                  | 占位文本                                          |
| showLabel         | `boolean`                                                                                                                                                                                     | `true`                                                               | 是否展示进度文本                                  |
| stripe            | `boolean`                                                                                                                                                                                     | `false`                                                              | 背景是否显示条纹                                  |
| animate           | `boolean`                                                                                                                                                                                     | `false`                                                              | type 为 line，可支持动画                          |
| map               | `string \| Array<string> \| Array<{value:number, color:string}>`                                                                                                                              | `['bg-danger', 'bg-warning', 'bg-info', 'bg-success', 'bg-success']` | 进度颜色映射                                      |
| threshold         | {value:[模板](../../docs/concepts/template), color?:[模板](../../docs/concepts/template)} \| Array<{value:[模板](../../docs/concepts/template), color?:[模板](../../docs/concepts/template)}> | `-`                                                                  | 阈值（刻度）                                      |
| showThresholdText | `boolean`                                                                                                                                                                                     | `false`                                                              | 是否显示阈值（刻度）数值                          |
| valueTpl          | `string`                                                                                                                                                                                      | `${value}%`                                                          | 自定义格式化内容                                  |
| strokeWidth       | `number`                                                                                                                                                                                      | line 类型为`10`，circle、dashboard 类型为`6`                         | 进度条线宽度                                      |
| gapDegree         | `number`                                                                                                                                                                                      | `75`                                                                 | 仪表盘缺角角度，可取值 0 ~ 295                    |
| gapPosition       | `string`                                                                                                                                                                                      | `bottom`                                                             | 仪表盘进度条缺口位置，可选`top bottom left right` |

## 动作表

当前组件对外暴露以下特性动作，其他组件可以通过指定`actionType: 动作名称`、`componentId: 该组件id`来触发这些动作，动作配置可以通过`args: {动作配置项名称: xxx}`来配置具体的参数，详细请查看[事件动作](../../docs/concepts/event-action#触发其他组件的动作)。

| 动作名称 | 动作配置                             | 说明         |
| -------- | ------------------------------------ | ------------ |
| reset    | -                                    | 将值重置为 0 |
| setValue | `value: string` \| `number` 更新的值 | 更新数据     |

### reset

```schema: scope="body"
{
  "type": "page",
  "body": [
    {
      "type": "progress",
      "name": "progress",
      "id": "progress",
      "value": 67
    },
    {
      "type": "button",
      "label": "重置值",
      "onEvent": {
        "click": {
          "actions": [
            {
              "actionType": "reset",
              "componentId": "progress"
            }
          ]
        }
      }
    }
  ]
}
```

### setValue

```schema: scope="body"
{
  "type": "page",
  "body": [
    {
      "type": "progress",
      "name": "progress",
      "id": "progress",
      "value": 67
    },
    {
      "type": "button",
      "label": "设置值",
      "onEvent": {
        "click": {
          "actions": [
            {
              "actionType": "setValue",
              "componentId": "progress",
              "args": {
                "value": 20
              }
            }
          ]
        }
      }
    }
  ]
}
```

---

### Zh CN Components Property (`docs/zh-CN/components/property.md`)

---
title: Property 属性表
description:
type: 0
group: ⚙ 组件
menuName: Property 属性表
icon:
order: 60
---

使用表格的方式显示只读信息，如产品详情页。

## 基本用法

```schema: scope="body"
{
  "type": "property",
  "title": "机器配置",
  "items": [
    {
      "label": "cpu",
      "content": "1 core"
    },
    {
      "label": "memory",
      "content": "4G"
    },
    {
      "label": "disk",
      "content": "80G"
    },
    {
      "label": "network",
      "content": "4M",
      "span": 2
    },
    {
      "label": "IDC",
      "content": "beijing"
    },
    {
      "label": "Note",
      "content": "其它说明",
      "span": 3
    }
  ]
}
```

## 简易模式

默认是表格模式，还可以通过 `"mode"="simple"` 改成简易模式，在这种模式下没有边框，属性名和值是通过 `separator` 来分隔

```schema: scope="body"
{
  "type": "property",
  "mode": "simple",
  "separator": "：",
  "items": [
    {
      "label": "cpu",
      "content": "1 core"
    },
    {
      "label": "memory",
      "content": "4G"
    },
    {
      "label": "disk",
      "content": "80G"
    },
    {
      "label": "network",
      "content": "4M",
      "span": 2
    },
    {
      "label": "IDC",
      "content": "beijing"
    },
    {
      "label": "Note",
      "content": "其它说明",
      "span": 3
    }
  ]
}
```

## 使用其它展现

`label` 和 `content` 均支持使用 `amis` 其它渲染组件，比如

```schema: scope="body"
{
  "type": "property",
  "items": [
    {
      "label": "tpl",
      "content": {
        "type": "tpl",
        "tpl": "1 <b>Core</b>"
      }
    },
    {
      "label": "icon",
      "content": {
        "type": "icon",
        "icon": "microchip"
      }
    },
    {
      "label": "图片",
      "content": {
        "type": "image",
        "src": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,w_216,l_1,f_jpg,q_80"
      }
    }
  ]
}
```

## 动态内容

属性表本身没有数据获取功能，需要结合 [service](./service) 来获取数据，下面的例子为了方便就直接放 page 下的 data 中了，它的效果和用 service 是一样的。

动态内容有两种情况：

1. label 固定、content 不同
2. label 和 content 都不确定

第一种情况只需要在 content 里使用变量即可，因为可以用任意 amis 节点。

```schema
{
  "type": "page",
  "data": {
    "cpu": "1 core",
    "memory": "4G",
    "disk": "80G"
  },
  "body": {
    "type": "property",
    "items": [
      {
        "label": "cpu",
        "content": "${cpu}"
      },
      {
        "label": "memory",
        "content": "${memory}"
      },
      {
        "label": "disk",
        "content": "${disk}"
      }
    ]
  }
}
```

第二种情况需要使用 `source` 属性来获取上下文中的内容。

```schema
{
  "type": "page",
  "data": {
    "title": "title1",
    "items": [
      {
        "label": "cpu",
        "content": "1 core"
      },
      {
        "label": "memory",
        "content": "4G"
      },
      {
        "label": "disk",
        "content": "80G"
      },
      {
        "label": "network",
        "content": "4M",
        "span": 2
      },
      {
        "label": "IDC",
        "content": "beijing"
      },
      {
        "label": "Note",
        "content": "其它说明",
        "span": 3
      }
    ]
  },
  "body": {
    "type": "property",
    "title": "${title}",
    "source": "${items}"
  }
}
```

## 样式控制

通过 `labelStyle` 和 `contentStyle` 来控制属性名和属性值的样式，比如水平及垂直方向的对齐方式：

```schema: scope="body"
{
  "type": "property",
  "labelStyle": {
    "textAlign": "left",
    "verticalAlign": "top"
  },
  "contentStyle": {
    "verticalAlign": "top"
  },
  "items": [
    {
      "label": "cpu",
      "content": "1 core"
    },
    {
      "label": "memory",
      "content": "4G"
    },
    {
      "label": "disk",
      "content": {
        "type": "tpl",
        "tpl": "C: 80G<br/>D: 1T<br/>E: 2T</pre>"
      }
    },
    {
      "label": "network",
      "content": "4M",
      "span": 2
    },
    {
      "label": "IDC",
      "content": "beijing"
    },
    {
      "label": "Note",
      "content": "其它说明",
      "span": 3
    }
  ]
}
```

如果是简易模式，因为合并到一个单元格中了，因此只能通过 `contentStyle` 设置单元格样式，`labelStyle` 只能设置属性名文本的样式。

```schema: scope="body"
{
  "type": "property",
  "mode": "simple",
  "labelStyle": {
    "fontWeight": "bold",
    "textTransform": "capitalize"
  },
  "contentStyle": {
    "verticalAlign": "top"
  },
  "items": [
    {
      "label": "cpu",
      "content": "1 core"
    },
    {
      "label": "memory",
      "content": "4G"
    },
    {
      "label": "disk",
      "content": {
        "type": "tpl",
        "tpl": "C: 80G<br/>D: 1T<br/>E: 2T</pre>"
      }
    },
    {
      "label": "network",
      "content": "4M",
      "span": 2
    },
    {
      "label": "IDC",
      "content": "beijing"
    },
    {
      "label": "Note",
      "content": "其它说明",
      "span": 3
    }
  ]
}
```

## 显示列数

通过 `column` 来控制一行显示几列，默认是 3 列，下面示例是改成 2 列的效果

```schema: scope="body"
{
  "type": "property",
  "column": 2,
  "items": [
    {
      "label": "cpu",
      "content": "1 core"
    },
    {
      "label": "memory",
      "content": "4G"
    },
    {
      "label": "disk",
      "content": "80G"
    },
    {
      "label": "IDC",
      "content": "beijing"
    },
    {
      "label": "network",
      "content": "4M",
      "span": 2
    },
    {
      "label": "Note",
      "content": "其它说明",
      "span": 2
    }
  ]
}
```

## 隐藏某个属性值

items 里的属性还支持 `visibleOn` 和 `hiddenOn` 表达式，能隐藏部分属性，如果有空间后续组件会自动补上来，如下示例的 memory 隐藏了：

```schema: scope="body"
{
  "type": "property",
  "items": [
    {
      "label": "cpu",
      "content": "1 core"
    },
    {
      "label": "memory",
      "content": "4G",
      "visibleOn": "data.cpu > 1"
    },
    {
      "label": "network",
      "content": "4M",
      "span": 2
    }
  ]
}
```

## 属性表

| 属性名            | 类型                                     | 默认值  | 说明                                   |
| ----------------- | ---------------------------------------- | ------- | -------------------------------------- |
| className         | `string`                                 |         | 外层 dom 的类名                        |
| style             | `object`                                 |         | 外层 dom 的样式                        |
| labelStyle        | `object`                                 |         | 属性名的样式                           |
| contentStyle      | `object`                                 |         | 属性值的样式                           |
| column            | `number`                                 | 3       | 每行几列                               |
| mode              | `string`                                 | 'table' | 显示模式，目前只有 'table' 和 'simple' |
| separator         | `string`                                 | ','     | 'simple' 模式下属性名和值之间的分隔符  |
| title             | `string`                                 |         | 标题                                   |
| source            | `string`                                 |         | 数据源                                 |
| items[].label     | `SchemaTpl`                              |         | 属性名                                 |
| items[].content   | `SchemaTpl`                              |         | 属性值                                 |
| items[].span      | `SchemaTpl`                              |         | 属性值跨几列                           |
| items[].visibleOn | [表达式](../../docs/concepts/expression) |         | 显示表达式                             |
| items[].hiddenOn  | [表达式](../../docs/concepts/expression) |         | 隐藏表达式                             |

---

### Zh CN Components Qrcode (`docs/zh-CN/components/qrcode.md`)

---
title: QRCode 二维码
description:
type: 0
group: ⚙ 组件
menuName: QRCode 二维码
icon:
order: 61
---

## 基本用法

```schema: scope="body"
{
    "type": "qr-code",
    "codeSize": 128,
    "value": "https://www.baidu.com"
}
```

> 根据 QR 码国际标准，二进制模式最多可存储`2953`字节的内容（1 中文汉字=2 字节）

## 配置背景色

背景色默认为`#fff`（纯白色）, `backgroundColor`属性可以修改背景色。

```schema: scope="body"
[
    {
        "type": "qr-code",
        "codeSize": 128,
        "backgroundColor": "#108cee",
        "foregroundColor": "#000",
        "value": "https://www.baidu.com"
    }
]
```

## 配置前景色

前景色默认为`#000`（纯黑色）, `foregroundColor`属性可以前景色。

```schema: scope="body"
[
    {
        "type": "qr-code",
        "codeSize": 128,
        "backgroundColor": "#fff",
        "foregroundColor": "#108cee",
        "value": "https://www.baidu.com"
    }
]
```

## 纠错等级

`level`属性可以设置二维码的纠错等级，纠错等级分为四种（`'L' 'M' 'Q' 'H'`），从左到右依次提升，默认为`'L'`。

```schema: scope="body"
{
  "type": "hbox",
  "columns": [
    {
      "type": "qr-code",
      "codeSize": 128,
      "level": "L",
      "value": "https://www.baidu.com"
    },
    {
      "type": "qr-code",
      "codeSize": 128,
      "level": "M",
      "value": "https://www.baidu.com"
    },
    {
      "type": "qr-code",
      "codeSize": 128,
      "level": "Q",
      "value": "https://www.baidu.com"
    },
    {
      "type": "qr-code",
      "codeSize": 128,
      "level": "H",
      "value": "https://www.baidu.com"
    }
  ]
}
```

## 嵌入图片

`imageSettings`属性可以设置二维码中嵌入的图片，`src`设置图片链接地址，图片大小默认为二维码大小的 10%，图片位置默认水平垂直居中。

> 1.10.0 及以上版本。
> 建议根据图片大小，调整二维码纠错等级，避免图片遮挡导致二维码无法被正确识别

```schema: scope="body"
{
    "type": "qr-code",
    "codeSize": 128,
    "level": "Q",
    "value": "https://www.baidu.com",
    "imageSettings": {
      "src": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,w_216,l_1,f_jpg",
    }
}
```

### 关联上下文变量

```schema: scope="body"
{
    "type": "page",
    "data": {
        "imgSrc": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,w_216,l_1,f_jpg"
    },
    "body": {
        "type": "qr-code",
        "codeSize": 128,
        "level": "Q",
        "value": "https://www.baidu.com",
        "imageSettings": {
            "width": 50,
            "height": 30,
            "src": "${imgSrc}"
        }
    }

}
```

### 图片宽高

`width` 和 `height` 可以设置图片的宽度和高度。

```schema: scope="body"
{
    "type": "qr-code",
    "codeSize": 128,
    "level": "Q",
    "value": "https://www.baidu.com",
    "imageSettings": {
      "src": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,w_216,l_1,f_jpg",
      "width": 50,
      "height": 30
    }
}
```

### 图片偏移量

以二维码**左上角**为原点，`x`，`y`分别设置图片的水平偏移量和垂直偏移量。示例通过`codeSize`和图片的`width` 和 `height` 计算出偏移量`{"x": 78, "y": 98}`，使图片位于右下角。

```schema: scope="body"
{
    "type": "qr-code",
    "codeSize": 128,
    "level": "Q",
    "value": "https://www.baidu.com",
    "imageSettings": {
      "src": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,w_216,l_1,f_jpg",
      "width": 50,
      "height": 30,
      "x": 78,
      "y": 98
    }
}
```

### 码眼\码点样式

- 码眼类型`eyeType`可配置`default`、`rounded`、`circle`
- 码眼边框大小`eyeBorderSize`可配置`default`、`sm`、`xs`
- 码眼边框`eyeBorderColor`和内部颜色`eyeInnerColor`可分别配置，默认使用`foregroundColor`
- 码点类型`pointType`可配置`default`、`circle`
- 码点大小`pointTypeSize`可配置`default`、`sm`、`xs`
- 码点大小可`pointSizeRandom`，增加大小随机

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 下载二维码

> 3.6.0 及以上版本

基于事件动作实现

```schema: scope="body"
[
  {
    "type": "action",
    "label": "下载二维码",
    "onEvent": {
        "click": {
          "actions": [
            {
              "actionType": "saveAs",
              "componentId": "qr-code-download",
              "args": {
                "name": "download.png"
              }
            }
          ]
        }
      }
  },
  {
    "type": "qr-code",
    "id": "qr-code-download",
    "codeSize": 128,
    "value": "https://www.baidu.com"
 }
]
```

需要注意这种方式不支持嵌入图片，如果要嵌入图片建议直接截图

## 属性表

| 属性名               | 类型                                 | 默认值                    | 说明                                                                                                                                  |
| -------------------- | ------------------------------------ | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| type                 | `string`                             | `"qr-code"`               | 指定为 QRCode 渲染器                                                                                                                  |
| mode                 | `string`                             | `"canvas"`                | 渲染模式，有`canvas`和`svg`两种                                                                                                       |
| className            | `string`                             |                           | 外层 Dom 的类名                                                                                                                       |
| qrcodeClassName      | `string`                             |                           | 二维码的类名                                                                                                                          |
| codeSize             | `number`                             | `128`                     | 二维码的宽高大小                                                                                                                      |
| backgroundColor      | `string`                             | `"#fff"`                  | 二维码背景色                                                                                                                          |
| foregroundColor      | `string`                             | `"#000"`                  | 二维码前景色                                                                                                                          |
| level                | `string`                             | `"L"`                     | 二维码复杂级别，有（'L' 'M' 'Q' 'H'）四种                                                                                             |
| value                | [模板](../../docs/concepts/template) | `"https://www.baidu.com"` | 扫描二维码后显示的文本，如果要显示某个页面请输入完整 url（`"http://..."`或`"https://..."`开头），支持使用 [模板](./concepts/template) |
| imageSettings        | `object`                             |                           | QRCode 图片配置                                                                                                                       |
| imageSettings.src    | `string`                             |                           | 图片链接地址                                                                                                                          |
| imageSettings.width  | `number`                             | 默认为`codeSize`的 10%    | 图片宽度                                                                                                                              |
| imageSettings.height | `number`                             | 默认为`codeSize`的 10%    | 图片高度                                                                                                                              |
| imageSettings.x      | `number`                             | 默认水平居中              | 图片水平方向偏移量                                                                                                                    |
| imageSettings.y      | `number`                             | 默认垂直居中              | 图片垂直方向偏移量                                                                                                                    |
| eyeType              | `string`                             | `"default"`               | 码眼类型，有`default`、`circle`、`rounded`三种                                                                                        |
| eyeBorderColor       | `string`                             | `"#000000"`               | 码眼边框颜色                                                                                                                          |
| eyeBorderSize        | `string`                             | `"default"`               | 码眼边框大小，有`default`、`sm`、`xs`三种                                                                                             |
| eyeInnerColor        | `string`                             | `"#000000"`               | 码眼内部颜色                                                                                                                          |
| pointType            | `string`                             | `"default"`               | 码点类型，有`default`、`circle`两种                                                                                                   |
| pointSize            | `string`                             | `"default"`               | 码点大小，有`default`、`sm`、`xs`三种                                                                                                 |
| pointSizeRandom      | `boolean`                            | `false`                   | 码点大小随机                                                                                                                          |

## 动作表

当前组件对外暴露以下特性动作，其他组件可以通过指定`actionType: 动作名称`、`componentId: 该组件id`来触发这些动作，动作配置可以通过`args: {动作配置项名称: xxx}`来配置具体的参数，详细请查看[事件动作](../../docs/concepts/event-action#触发其他组件的动作)。

| 动作名称 | 动作配置               | 说明     |
| -------- | ---------------------- | -------- |
| saveAs   | `name?: string` 文件名 | 下载文档 |

---

### Zh CN Components Radios (`docs/zh-CN/components/radios.md`)

---
title: Radios 单选框
description:
type: 0
group: null
menuName: Radios 单选框
icon:
order: 36
---

## 基本用法

```schema: scope="body"
{
  "type": "form",
  "body": [
    {
      "name": "radios",
      "type": "radios",
      "label": "radios",
      "options": [
        {
          "label": "OptionA",
          "value": "a"
        },
        {
          "label": "OptionB",
          "value": "b"
        },
        {
          "label": "OptionC",
          "value": "c"
        },
        {
          "label": "OptionD",
          "value": "d"
        }
      ]
    }
  ]
}
```

## 属性表

当做选择器表单项使用时，除了支持 [普通表单项属性表](./formitem#%E5%B1%9E%E6%80%A7%E8%A1%A8) 中的配置以外，还支持下面一些配置

| 属性名          | 类型                                      | 默认值    | 说明                                                                                        |
| --------------- | ----------------------------------------- | --------- | ------------------------------------------------------------------------------------------- |
| options         | `Array<object>`或`Array<string>`          |           | [选项组](./options#%E9%9D%99%E6%80%81%E9%80%89%E9%A1%B9%E7%BB%84-options)                   |
| source          | `string`或 [API](../../../docs/types/api) |           | [动态选项组](./options#%E5%8A%A8%E6%80%81%E9%80%89%E9%A1%B9%E7%BB%84-source)                |
| labelField      | `boolean`                                 | `"label"` | [选项标签字段](./options#%E9%80%89%E9%A1%B9%E6%A0%87%E7%AD%BE%E5%AD%97%E6%AE%B5-labelfield) |
| valueField      | `boolean`                                 | `"value"` | [选项值字段](./options#%E9%80%89%E9%A1%B9%E5%80%BC%E5%AD%97%E6%AE%B5-valuefield)            |
| columnsCount    | `number`                                  | `1`       | 选项按几列显示，默认为一列                                                                  |
| autoFill        | `object`                                  |           | [自动填充](./options#%E8%87%AA%E5%8A%A8%E5%A1%AB%E5%85%85-autofill)                         |
| optionClassName | `string`                                  |           | 选项 CSS 类名                                                                               |

---

### Zh CN Components Remark (`docs/zh-CN/components/remark.md`)

---
title: Remark 标记
description:
type: 0
group: ⚙ 组件
menuName: Remark
icon:
order: 62
---

用于展示提示文本，和表单项中的 remark 属性类型。

## 基本用法

```schema
{
    "type": "page",
    "body": {
        "type": "remark",
        "content": "这是一段提醒"
    }
}
```

## 图标形状

```schema
{
    "type": "page",
    "body": {
        "type": "remark",
        "content": "这是一段提醒",
        "shape": "circle"
    }
}
```
## 可配置标题

```schema
{
    "type": "page",
    "body": {
        "type": "remark",
        "content": {
            "title": "标题",
            "body": "这是一段提醒"
        }
    }
}
```

## 支持变量

```schema
{
    "type": "page",
    "data": {
        "github": "https://github.com/"
    },
    "body": [
        {
            "type": "remark",
            "content": "${github}"
        },
        {
            "type": "remark",
            "content": {
                "title": "${github|raw}",
                "body": "${github}"
            }
        }
    ]
}
```

## 弹出位置

```schema: scope="body"
[
    {
        "type": "remark",
        "content": "向上",
        "placement": "top"
    },
    {
        "type": "remark",
        "content": "向下",
        "placement": "bottom"
    },
    {
        "type": "remark",
        "content": "向左",
        "placement": "left"
    },
    {
        "type": "remark",
        "content": "向右",
        "placement": "right"
    }
]
```

## 属性表

| 属性名    | 类型     | 默认值                  | 说明          |
| --------- | -------- | ----------------------- | ------------- |
| type      | `string` |                         | `remark`      |
| className | `string` |                         | 外层 CSS 类名 |
| content   | `string` |                         | 提示文本      |
| placement | `string` |                         | 弹出位置      |
| trigger   | `string` | `['hover', 'focus']`    | 触发条件      |
| icon      | `string` | `fa fa-question-circle` | 图标          |
| shape     | `'circle' \| 'square'`             | 图标形状       |

---

### Zh CN Components Search Box (`docs/zh-CN/components/search-box.md`)

---
title: Search Box 搜索框
description:
type: 0
group: ⚙ 组件
menuName: Search Box
icon:
---

## 基本用法

用于展示一个简单搜索框，通常需要搭配其他组件使用。比如 page 配置 `initApi` 后，可以用来实现简单数据过滤查找，`name` keywords 会作为参数传递给 page 的 `initApi`。

```schema
{
    "type": "page",
    "initApi": "/api/mock2/page/initData?keywords=${keywords}",
    "body": [
      {
        "type": "search-box",
        "name": "keywords"
      },

      {
        "type": "tpl",
        "tpl": "<p>关键字：${keywords}</p><p>返回结果：${&|json}</p>"
      }
    ]
}
```

## 禁用样式

> `6.0.0`及以上版本

```schema
{
    "type": "page",
    "initApi": "/api/mock2/page/initData?keywords=${keywords}",
    "body": [
      {
        "type": "flex",
        "direction": "column",
        "justify": "flex-start",
        "alignItems": "flex-start",
        "items": [
          {
            "type": "search-box",
            "name": "keywords",
            "disabled": true,
            "style": {
              "marginBottom": "10px"
            }
          },
          {
            "type": "search-box",
            "name": "keywords",
            "mini": true,
            "disabled": true
          }
        ]
      }
    ]
}
```

## 加载状态

> `6.0.0` 及以上版本

设置`"loading": true`, 标识开关操作的异步任务仍在执行中。另外`loadingOn`支持表达式，配合`ajax`动作，实现搜索操作时的loading状态。

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 加强样式

```schema
{
    "type": "page",
    "initApi": "/api/mock2/page/initData?keywords=${keywords}",
    "body": [
      {
        "type": "search-box",
        "name": "keywords",
        "enhance": true
      },

      {
        "type": "tpl",
        "tpl": "<p>关键字：${keywords}</p><p>返回结果：${&|json}</p>"
      }
    ]
}
```

## 可清除

```schema
{
    "type": "page",
    "initApi": "/api/mock2/page/initData?keywords=${keywords}",
    "body": [
      {
        "type": "search-box",
        "name": "keywords",
        "clearable": true
      },

      {
        "type": "tpl",
        "tpl": "<p>关键字：${keywords}</p><p>返回结果：${&|json}</p>"
      }
    ]
}
```

### 清除后立即搜索

> `2.8.0` 及以上版本

设置`"clearAndSubmit": true`后，清空搜索框内容后立即执行搜索，与`searchImediately`不同的是，`clearAndSubmit`仅作用于清空输入框的动作，而`searchImediately`会影响所有搜索动作。

```schema
{
    "type": "page",
    "initApi": "/api/mock2/page/initData?keywords=${keywords}",
    "body": [
      {
        "type": "search-box",
        "name": "keywords",
        "clearable": true,
        "clearAndSubmit": true
      },

      {
        "type": "tpl",
        "tpl": "<p>关键字：${keywords}</p><p>返回结果：${&|json}</p>"
      }
    ]
}
```

## mini 版本

```schema
{
    "type": "page",
    "initApi": "/api/mock2/page/initData?keywords=${keywords}",
    "body": [
      {
        "type": "search-box",
        "name": "keywords",
        "mini": true
      },

      {
        "type": "tpl",
        "tpl": "<p>关键字：${keywords}</p><p>返回结果：${&|json}</p>"
      }
    ]
}
```

## 与 CRUD 搭配

```schema: scope="body"
{
    "type": "crud",
    "api": "/api/mock2/sample",
    "syncLocation": false,
    "headerToolbar": [
      {
        "type": "search-box",
        "name": "keywords",
        "align": "right",
        "placeholder": "关键字检索"
      }
    ],
    "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "engine",
            "label": "Rendering engine"
        },
        {
            "name": "browser",
            "label": "Browser"
        },
        {
            "name": "platform",
            "label": "Platform(s)"
        },
        {
            "name": "version",
            "label": "Engine version"
        },
        {
            "name": "grade",
            "label": "CSS grade"
        }
    ]
}
```

## 与 Service 搭配

```schema
{
    "type": "page",
    "body": [
      {
        "type": "service",
        "api": "/api/mock2/page/initData?keywords=${keywords}",
        "body": [
          {
            "type": "search-box",
            "name": "keywords"
          },

          {
            "type": "tpl",
            "tpl": "<p>关键字：${keywords}</p><p>返回结果：${&|json}</p>"
          }
        ]
      }

    ]
}
```

## 立刻搜索模式

设置 `"searchImediately": true` 实现输入时即搜索

```schema
{
    "type": "page",
    "body": [
      {
        "type": "service",
        "api": "/api/mock2/page/initData?keywords=${keywords}",
        "body": [
          {
            "type": "search-box",
            "name": "keywords",
            "searchImediately": true
          },
          {
            "type": "tpl",
            "tpl": "<p>关键字：${keywords}</p><p>返回结果：${&|json}</p>"
          }
        ]
      }
    ]
}
```

## 属性表

| 属性名           | 类型      | 默认值 | 说明                         | 版本    |
| ---------------- | --------- | ------ | ---------------------------- | ------- |
| type             | `string`  |        | `search-box`                 |
| className        | `string`  |        | 外层 CSS 类名                |
| mini             | `boolean` |        | 是否为 mini 模式             |
| searchImediately | `boolean` |        | 是否立即搜索                 |
| clearAndSubmit   | `boolean` |        | 清空搜索框内容后立即执行搜索 | `2.8.0` |
| disabled   | `boolean` |    `false`    | 是否为禁用状态 | `6.0.0` |
| loading   | `boolean` |    `false`    | 是否处于加载状态 | `6.0.0` |

## 事件表

> 2.4.1 及以上版本

当前组件会对外派发以下事件，可以通过`onEvent`来监听这些事件，并通过`actions`来配置执行的动作，在`actions`中可以通过`${事件参数名}`或`${event.data.[事件参数名]}`来获取事件产生的数据，详细请查看[事件动作](../../docs/concepts/event-action)。

> `[name]`表示当前组件绑定的名称，即`name`属性，如果没有配置`name`属性，则通过`value`取值。

| 事件名称 | 事件参数                  | 说明                 |
| -------- | ------------------------- | -------------------- |
| search   | `[name]: string` 组件的值 | 点击搜索图标时触发   |
| change   | `[name]: string` 组件的值 | 输入框值变化时触发   |
| focus    | `[name]: string` 组件的值 | 输入框获取焦点时触发 |
| blur     | `[name]: string` 组件的值 | 输入框失去焦点时触发 |

### search

```schema
{
  "type": "page",
  "initApi": "/api/mock2/page/initData?keywords=${keywords}",
  "body": [
    {
      "type": "search-box",
      "name": "keywords",
      "onEvent": {
        "search": {
          "actions": [
            {
              "actionType": "toast",
              "args": {
                "msg": "${keywords}"
              }
            }
          ]
        }
      }
    }
  ]
}
```

### change

```schema: scope="body"
{
  "type": "page",
  "initApi": "/api/mock2/page/initData?keywords=${keywords}",
  "body": [
    {
      "type": "search-box",
      "name": "keywords",
      "onEvent": {
        "change": {
          "actions": [
            {
              "actionType": "toast",
              "args": {
                "msg": "${keywords}"
              }
            }
          ]
        }
      }
    }
  ]
}
```

### focus

```schema: scope="body"
{
  "type": "page",
  "initApi": "/api/mock2/page/initData?keywords=${keywords}",
  "body": [
    {
      "type": "search-box",
      "name": "keywords",
      "onEvent": {
        "focus": {
          "actions": [
            {
              "actionType": "toast",
              "args": {
                "msg": "${keywords}"
              }
            }
          ]
        }
      }
    }
  ]
}
```

### blur

```schema: scope="body"
{
  "type": "page",
  "initApi": "/api/mock2/page/initData?keywords=${keywords}",
  "body": [
    {
      "type": "search-box",
      "name": "keywords",
      "onEvent": {
        "blur": {
          "actions": [
            {
              "actionType": "toast",
              "args": {
                "msg": "${keywords}"
              }
            }
          ]
        }
      }
    }
  ]
}
```

## 动作表

> 2.4.1 及以上版本

当前组件对外暴露以下特性动作，其他组件可以通过指定`actionType: 动作名称`、`componentId: 该组件id`来触发这些动作，动作配置可以通过`args: {动作配置项名称: xxx}`来配置具体的参数，详细请查看[事件动作](../../docs/concepts/event-action#触发其他组件的动作)。

| 动作名称 | 动作配置                 | 说明     |
| -------- | ------------------------ | -------- |
| clear    | -                        | 清空     |
| setValue | `value: string` 更新的值 | 更新数据 |

### clear

```schema: scope="body"
{
  "type": "page",
  "initApi": "/api/mock2/page/initData?keywords=${keywords}",
  "body": [
    {
      "type": "search-box",
      "name": "keywords",
      "id": "s01"
    },
    {
      "type": "button",
      "label": "清除",
      "onEvent": {
        "click": {
          "actions": [
            {
              "actionType": "clear",
              "componentId": "s01"
            }
          ]
        }
      }
    }
  ]
}
```

### setValue

```schema: scope="body"
{
  "type": "page",
  "initApi": "/api/mock2/page/initData?keywords=${keywords}",
  "body": [
    {
      "type": "search-box",
      "name": "keywords",
      "id": "s02"
    },
    {
      "type": "button",
      "label": "设置关键字",
      "onEvent": {
        "click": {
          "actions": [
            {
              "actionType": "setValue",
              "componentId": "s02",
              "args": {
                "value": "amis"
              }
            }
          ]
        }
      }
    }
  ]
}
```

---

### Zh CN Components Service (`docs/zh-CN/components/service.md`)

---
title: Service 功能型容器
description:
type: 0
group: ⚙ 组件
menuName: Service
icon:
order: 63
---

amis 中部分组件，作为展示组件，自身没有**使用接口初始化数据域的能力**，例如：[Table](./table)、[Cards](./cards)、[List](./list)等，他们需要使用某些配置项，例如`source`，通过[数据映射](../../docs/concepts/data-mapping)功能，在当前的 **数据链** 中获取数据，并进行数据展示。

而`Service`组件就是专门为该类组件而生，它的功能是：**配置初始化接口，进行数据域的初始化，然后在`Service`内容器中配置子组件，这些子组件通过数据链的方法，获取`Service`所拉取到的数据**

## 基本使用

最基本的使用，是配置初始化接口`api`，将接口返回的数据添加到自身的数据域中，以供子组件通过[数据链](../../docs/concepts/datascope-and-datachain#%E6%95%B0%E6%8D%AE%E9%93%BE)进行获取使用。

```schema: scope="body"
{
    "type": "service",
    "api": "/api/mock2/page/initData",
    "body": {
        "type": "panel",
        "title": "$title",
        "body": "现在是：${date}"
    }
}
```

你可以通过查看网络面板看到，`service`接口返回的数据结构为：

```json
{
  "status": 0,
  "msg": "",
  "data": {
    "title": "Test Page Component",
    "date": "2017-10-13"
  }
}
```

在`service`的子组件中，就可以使用`${title}`和`${date}`展示数据

## 展示列表

另外一种使用较为频繁的场景是：serivce + table 进行列表渲染

```schema: scope="body"
{
    "type": "service",
    "api": "/api/mock2/crud/table?perPage=5",
    "body": [
        {
            "type": "table",
            "title": "表格1",
            "source": "$rows",
            "columns": [
                {
                    "name": "engine",
                    "label": "Engine"
                },
                {
                    "name": "version",
                    "label": "Version"
                }
            ]
        },
        {
            "type": "table",
            "source": "$rows",
            "columns": [
                {
                    "name": "engine",
                    "label": "Engine"
                },
                {
                    "name": "version",
                    "label": "Version"
                }
            ]
        }
    ]
}
```

上例中 service 接口返回数据结构如下：

```
/* Detailed source-code truncated for AI context efficiency. */
```

`table`中配置`source`属性为`${rows}`就可以获取到`rows`变量的数据，并用于展示。

## 动态渲染页面

`Service` 还有个重要的功能就是支持配置 `schemaApi`，通过它可以实现动态渲染页面内容。

```schema: scope="body"
{
  "type": "service",
  "schemaApi": "/api/mock2/service/schema?type=tabs"
}
```

同样观察`schemaApi接口`返回的数据结构：

```json
{
  "status": 0,
  "msg": "",
  "data": {
    "type": "tabs",
    "tabs": [
      {
        "title": "TabA",
        "body": "卡片A内容"
      },
      {
        "title": "TabB",
        "body": "卡片B内容"
      }
    ]
  }
}
```

它将`data`返回的对象作为 amis 页面配置，进行了解析渲染，实现动态渲染页面的功能。

### jsonp 请求

`schemaApi` 同样支持 `jsonp` 请求，完整用法请参考 amis-admin 项目。

```schema: scope="body"
{
  "type": "service",
  "schemaApi": "jsonp:/api/mock2/service/jsonp"
}
```

`schemaApi接口` 返回的内容其实是一段立即执行的 js 代码。我们可以通过 `callback` 参数执行函数名，或者通过 `request._callback` 获取

```js
(function () {
  window.axiosJsonpCallbackxxxx &&
    window.axiosJsonpCallbackxxxx({
      status: 0,
      msg: '',
      data: {
        type: 'page',
        title: 'jsonp 示例',
        body: 'this is tpl from jsonp'
      }
    });
})();
```

### js 请求

> 2.1.0 及以上版本

`schemaApi` 支持 `js` 请求，它会发起一个 xhr 请求去下载 js 文件后执行

```schema: scope="body"
{
  "type": "service",
  "schemaApi": "js:/api/mock2/service/jsschema"
}
```

这个接口的返回结果期望是一段 JavaScript 代码，和普通 json 返回结果最大的不同是这里可以执行 JavaScript 代码，比如支持 onClick 函数

```javascript
return {
  type: 'button',
  label: '按钮修改',
  onClick: (e, props) => {
    alert('消息通知');
  }
};
```

这段代码里可以通过 api 变量拿到当前请求的 api 参数，比如 url 地址，可以通过判断进行二次处理

```javascript
console.log(api);
return {
  type: 'button',
  label: '按钮修改',
  onClick: (e, props) => {
    alert(api.url);
  }
};
```

## 动态渲染表单项

默认 Service 可以通过配置`schemaApi` [动态渲染页面内容](../service#%E5%8A%A8%E6%80%81%E6%B8%B2%E6%9F%93%E9%A1%B5%E9%9D%A2)，但是如果想渲染表单项，请返回下面这种格式：

```json
{
  "status": 0,
  "msg": "",
  "data": {
    "type": "container",
    "body": [
      {
        "type": "input-text",
        "name": "text",
        "label": "文本输入"
      }
    ]
  }
}
```

例如下例：

```schema: scope="form-item2"
{
  "type": "service",
  "schemaApi": "/api/mock2/service/schema?type=controls"
}
```

`schemaApi` 除了能返回表单项之外，还能同时返回表单数据，如果你这样返回接口

```json
{
  "status": 0,
  "msg": "",
  "data": {
    "data": {
      "a": "b" // 这样返回的选项会选中第二个选项B
    },
    "body": [
      {
        "type": "select",
        "name": "a",
        "label": "选项",
        "options": [
          {"label": "A", "value": "a"},
          {"label": "B", "value": "b"}
        ]
      }
    ]
  }
}
```

## 接口联动

`api`和`schemaApi`都支持[接口联动](../../docs/concepts/linkage#%E6%8E%A5%E5%8F%A3%E8%81%94%E5%8A%A8)

```schema: scope="body"
{
    "title": "",
    "type": "form",
    "api": "/api/mock/saveForm?waitSeconds=1",
    "mode": "horizontal",
    "body": [
        {
        "label": "数据模板",
        "type": "select",
        "name": "tpl",
        "value": "tpl1",
        "size": "sm",
        "options": [
            {
            "label": "模板1",
            "value": "tpl1"
            },
            {
            "label": "模板2",
            "value": "tpl2"
            },
            {
            "label": "模板3",
            "value": "tpl3"
            }
        ],
        "description": "<span class=\"text-danger\">请修改该下拉选择器查看效果</span>"
        },
        {
        "type": "service",
        "api": "/api/mock2/form/initData?tpl=${tpl}",
        "body": [
            {
            "label": "名称",
            "type": "input-text",
            "name": "name"
            },
            {
            "label": "作者",
            "type": "input-text",
            "name": "author"
            },
            {
            "label": "请求时间",
            "type": "input-datetime",
            "name": "date"
            }
        ]
        }
    ],
    "actions": []
}
```

上例可看到，变更**数据模板**的值，会触发 service 重新请求，并更新当前数据域中的数据

更多相关见[接口联动](../../docs/concepts/linkage#%E6%8E%A5%E5%8F%A3%E8%81%94%E5%8A%A8)

## 定时轮询刷新

设置 `interval` 可以定时刷新 `api` 和 `schemaApi` 接口，单位是毫秒，如`"interval": 2000` 则设置轮询间隔为 2s ，注意最小间隔时间是 1 秒。支持通过`stopAutoRefreshWhen`表达式定义轮询停止条件。

```schema: scope="body"
{
    "type": "service",
    "api": "/api/mock2/number/random?waitSeconds=1",
    "interval": 2000,
    "stopAutoRefreshWhen": "this.random === 6",
    "body": {
        "type": "panel",
        "title": "随机数字",
        "body": "现在是：${random}"
    }
}
```

### 静默轮询

设置`silentPolling: true`可以关闭等待接口加载时的 loading 动画，该配置仅在配置`interval`时生效。

```schema: scope="body"
{
    "type": "service",
    "api": "/api/mock2/number/random?waitSeconds=1",
    "interval": 2000,
    "silentPolling": true,
    "stopAutoRefreshWhen": "this.random === 6",
    "body": {
        "type": "panel",
        "title": "随机数字",
        "body": "现在是：${random}"
    }
}
```

## 通过 WebSocket 实时获取数据

Service 支持通过 WebSocket 获取数据，只需要设置 ws（由于无示例服务，所以无法在线演示）。

```json
{
  "type": "service",
  "ws": "ws://localhost:8777",
  "body": {
    "type": "panel",
    "title": "$title",
    "body": "随机数：${random}"
  }
}
```

> 1.4.0 及以上版本

或者是对象的方式支持配置初始 `data`，这个 data 会在建立连接时发送初始数据

```json
{
  "type": "service",
  "ws": {
    "url": "ws://localhost:8777?name=${name}",
    "data": {
      "name": "${name}"
    }
  },
  "body": {
    "label": "名称",
    "type": "static",
    "name": "name"
  }
}
```

可以只设置 ws，通过 ws 来获取所有数据，也可以同时设置 api 和 ws，让 api 用于获取全部数据，而 ws 用于获取实时更新的数据。

后端实现示例，基于 [ws](https://github.com/websockets/ws)：

```javascript
const WebSocket = require('ws');

const ws = new WebSocket.Server({port: 8777});

ws.on('connection', function connection(ws) {
  setInterval(() => {
    const random = Math.floor(Math.random() * Math.floor(100));
    // 返回给 amis 的数据
    const data = {
      random
    };
    // 发送前需要转成字符串
    ws.send(JSON.stringify(data));
  }, 500);
});
```

WebSocket 客户端的默认实现是使用标准 WebSocket，如果后端使用定制的 WebSocket，比如 socket.io，可以通过覆盖 `env.wsFetcher` 来自己实现数据获取方法，默认实现是：

> 1.4.0 及以上版本修改了 ws 类型，将之前的字符串改成了对象的方式，会有两个参数 url 和 body

下面是目前 amis 中 WebSocket 支持的默认实现：

```javascript
wsFetcher(ws, onMessage, onError) {
    if (ws) {
      const socket = new WebSocket(ws.url);
      socket.onopen = event => {
        if (ws.body) {
          socket.send(JSON.stringify(ws.body));
        }
      };
      socket.onmessage = event => {
        if (event.data) {
          let data;
          try {
            data = JSON.parse(event.data);
          } catch (error) {}
          if (typeof data !== 'object') {
            let key = ws.responseKey || 'data';
            data = {
              [key]: event.data
            };
          }
          onMessage(data);
        }
      };
      socket.onerror = onError;
      return {
        close: socket.close
      };
    } else {
      return {
        close: () => {}
      };
    }
  }
```

通过 onMessage 来通知 amis 数据修改了，并返回 close 函数来关闭连接。

> 1.8.0 及以上版本

如果 WebSocket 返回的结果不是 JSON 而只是某个字符串，需要配置 `responseKey` 属性来将这个结果放在这个 key 上，比如下面的例子

```json
{
  "type": "service",
  "ws": {
    "url": "ws://localhost:8777?name=${name}",
    "data": {
      "name": "${name}"
    },
    "responseKey": "name"
  },
  "body": {
    "label": "名称",
    "type": "static",
    "name": "name"
  }
}
```

对应的后端就只需要返回字符串

```javascript
const WebSocket = require('ws');

const ws = new WebSocket.Server({port: 8777});

ws.on('connection', function connection(ws) {
  setInterval(() => {
    const random = Math.floor(Math.random() * Math.floor(100));
    ws.send(random);
  }, 500);
});
```

## 调用外部函数获取数据

> 1.4.0 及以上版本

对于更复杂的数据获取情况，可以使用 `dataProvider` 属性来实现外部函数获取数据，它支持字符串和函数两种形式

```schema: scope="body"
{
    "type": "service",
    "dataProvider": "setData({ now: new Date().toString() })",
    "body": {
        "type": "tpl",
        "tpl": "现在是：${now}"
    }
}
```

函数将会传递两个参数：`data` 和 `setData`，其中 `data` 可以拿到上下文数据，而 `setData` 函数可以用来更新数据，比如下面的例子

```schema: scope="body"
{
    "type": "service",
    "dataProvider": "const timer = setInterval(() => { setData({date: new Date().toString()}) }, 1000); return () => { clearInterval(timer) }",
    "body": {
        "type": "tpl",
        "tpl": "现在是：${date}"
    }
}
```

上面这个例子还返回了一个函数，这个函数会在组件销毁的时候执行，可以用来清理资源。

下面是使用函数类型的示例，注意这个示例不能放在 JSON 中，只能在 jssdk 或 react 项目里使用。

```javascript
{
    "type": "service",
    "dataProvider": (data, setData) => {
      const timer = setInterval(() => {
        setData({date: new Date().toString()})
      }, 1000);
      return () => { clearInterval(timer) }
    },
    "body": {
        "type": "tpl",
        "tpl": "现在是：${now}"
    }
}
```

> 1.8.0 及以上版本

新增了一个 `env` 属性，可以调用系统环境中的方法，比如 env.fetcher、tracker 等，比如下面的例子会调用 `env.notify` 来弹出提示

```javascript
{
    "type": "service",
    "dataProvider": "env.notify('info', 'msg')"
}
```

### 函数触发事件

> 2.3.0 及以上版本

```schema: scope="body"
{
    "type": "service",
    "api": "/api/mock2/page/initData",
    "dataProvider": {
        "inited": "setData({ addedNumber: data.number + 1  })",
        "onApiFetched": "setData({ year: new Date(data.date).getFullYear(),  })"
    },
    "data": {
        "number": 8887
    },
    "body": {
        "type": "panel",
        "title": "$title",
        "body": [
            {
                "type": "tpl",
                "wrapperComponent": "p",
                "tpl": "静态数字为：<strong>${addedNumber}</strong>"
            },
            {
                "type": "tpl",
                "wrapperComponent": "p",
                "tpl": "接口返回值的日期为：<strong>${date}</strong>"
            },
            {
                "type": "tpl",
                "wrapperComponent": "p",
                "tpl": "接口返回值的年份为：<strong>${year}</strong>"
            },
        ]
    }
}
```

## 隐藏错误信息

> 2.8.1 及以上版本

默认会将接口返回的错误信息展示在 Service 的顶部区域，可以通过设置`"showErrorMsg": false`隐藏错误提示。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/mock2/page/initDataError",
  "body": [
    {
      "type": "tpl",
      "tpl": "展示错误信息"
    },
    {
      "type": "icon",
      "icon": "fa-solid fa-arrow-up"
    }
  ]
}
```

设置`"showErrorMsg": false`隐藏错误提示，仅保留 toast 提示

```schema: scope="body"
{
  "type": "service",
  "api": "/api/mock2/page/initDataError",
  "showErrorMsg": false,
  "body": [
    {
      "type": "tpl",
      "tpl": "不展示错误信息"
    }
  ]
}
```

## 属性表

| 属性名                | 类型                                                                                            | 默认值         | 说明                                                                          | 版本                                                                                    |
| --------------------- | ----------------------------------------------------------------------------------------------- | -------------- | ----------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
| type                  | `string`                                                                                        | `"service"`    | 指定为 service 渲染器                                                         |
| className             | `string`                                                                                        |                | 外层 Dom 的类名                                                               |
| body                  | [SchemaNode](../../docs/types/schemanode)                                                       |                | 内容容器                                                                      |
| api                   | [API](../../docs/types/api)                                                                     |                | 初始化数据域接口地址                                                          |
| ws                    | `string`                                                                                        |                | WebScocket 地址                                                               |
| dataProvider          | `string \| Record<"inited" \| "onApiFetched" \| "onSchemaApiFetched" \| "onWsFetched", string>` |                | 数据获取函数                                                                  | <ul><li>`1.4.0`</li><li>`1.8.0`支持`env`参数</li><li>`2.3.0` 支持基于事件触发</li></ul> |
| initFetch             | `boolean`                                                                                       |                | 是否默认拉取                                                                  |
| schemaApi             | [API](../../docs/types/api)                                                                     |                | 用来获取远程 Schema 接口地址                                                  |
| initFetchSchema       | `boolean`                                                                                       |                | 是否默认拉取 Schema                                                           |
| messages              | `Object`                                                                                        |                | 消息提示覆写，默认消息读取的是接口返回的 toast 提示文字，但是在此可以覆写它。 |
| messages.fetchSuccess | `string`                                                                                        |                | 接口请求成功时的 toast 提示文字                                               |
| messages.fetchFailed  | `string`                                                                                        | `"初始化失败"` | 接口请求失败时 toast 提示文字                                                 |
| interval              | `number`                                                                                        |                | 轮询时间间隔，单位 ms(最低 1000)                                              |
| silentPolling         | `boolean`                                                                                       | `false`        | 配置轮询时是否显示加载动画                                                    |
| stopAutoRefreshWhen   | [表达式](../../docs/concepts/expression)                                                        |                | 配置停止轮询的条件                                                            |
| showErrorMsg          | `boolean`                                                                                       | `true`         | 是否以 Alert 的形式显示 api 接口响应的错误信息，默认展示                      | `2.8.1`                                                                                 |

## 事件表

当前组件会对外派发以下事件，可以通过`onEvent`来监听这些事件，并通过`actions`来配置执行的动作，在`actions`中可以通过`${事件参数名}`或`${event.data.[事件参数名]}`来获取事件产生的数据，详细请查看[事件动作](../../docs/concepts/event-action)。

> `[name]`为当前数据域中的字段名，例如：当前数据域为 {username: 'amis'}，则可以通过${username}获取对应的值。

| 事件名称          | 事件参数                                                                                                                                                                                   | 说明                                                |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------- |
| init              | -                                                                                                                                                                                          | 组件实例被创建并插入 DOM 中时触发。2.4.1 及以上版本 |
| fetchInited       | `responseData: any` 请求的响应数据</br>`responseStatus: number` 响应状态，0 表示成功</br>`responseMsg: string`响应消息, `error`表示接口是否成功<br/>`[name]: any` 当前数据域中指定字段的值 | api 接口请求完成时触发                              |
| fetchSchemaInited | `responseData: any` 请求的响应数据</br>`responseStatus: number` 响应状态，0 表示成功</br>`responseMsg: string`响应消息, `error`表示接口是否成功<br/>`[name]: any` 当前数据域中指定字段的值 | schemaApi 接口请求完成时触发                        |

### init

开始初始化。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/mock2/page/initData",
  "body": {
    "type": "panel",
    "title": "$title",
    "body": "现在是：${date}"
  },
  "onEvent": {
    "init": {
      "actions": [
        {
          "actionType": "toast",
          "args": {
            "msg": "init"
          }
        }
      ]
    }
  }
}
```

### fetchInited

api 接口请求完成。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/mock2/page/initData",
  "body": [
    {
      "type": "panel",
      "title": "$title",
      "body": "现在是：${date}"
    }
  ],
  "onEvent": {
    "fetchInited": {
      "actions": [
        {
          "actionType": "toast",
          "args": {
            "msg": "title:${event.data.responseData.title}，date:${date}，status:${event.data.responseStatus}"
          }
        }
      ]
    }
  }
}
```

### fetchSchemaInited

schemaApi 接口请求完成。

```schema: scope="body"
[
  {
    "type": "service",
    "schemaApi": "/api/mock2/service/schema?type=tabs",
    "onEvent": {
      "fetchSchemaInited": {
        "actions": [
          {
            "actionType": "toast",
            "args": {
              "msg": "type:${event.data.responseData.type}，status:${event.data.responseStatus}"
            }
          }
        ]
      }
    }
  }
]
```

## 动作表

当前组件对外暴露以下特性动作，其他组件可以通过指定`actionType: 动作名称`、`componentId: 该组件id`来触发这些动作，详细请查看[事件动作](../../docs/concepts/event-action#触发其他组件的动作)。

| 动作名称 | 动作配置 | 说明                                              |
| -------- | -------- | ------------------------------------------------- |
| reload   | -        | 重新加载，调用 `api`，刷新数据域数据              |
| rebuild  | -        | 重新构建，调用 `schemaApi`，重新构建容器内 Schema |
| setValue | -        | 更新数据域数据                                    |

### reload

#### 只做刷新

重新发送`api`请求，刷新 Page 时，只配置`componentId`目标组件 ID 即可。

```schema: scope="body"
[
  {
    "type": "button",
    "label": "刷新请求",
    "onEvent": {
      "click": {
        "actions": [
          {
            "componentId": "service-reload",
            "actionType": "reload"
          }
        ]
      }
    }
  },
  {
    "type": "service",
    "id": "service-reload",
    "name": "service-reload",
    "api": "/api/mock2/number/random",
    "body": "现在是：${random}"
  }
]
```

#### 发送数据并刷新

刷新 Service 组件时，如果配置了`data`，将发送`data`给目标组件，并将该数据合并到目标组件的数据域中（如果配置`"dataMergeMode": "override"`将覆盖目标组件的数据），然后重新请求数据。

```schema: scope="body"
[
  {
    "type": "button",
    "label": "刷新请求",
    "onEvent": {
      "click": {
        "actions": [
          {
            "componentId": "service-reload",
            "actionType": "reload",
            "data": {
              "date": "${NOW()}"
            }
          }
        ]
      }
    }
  },
  {
    "type": "service",
    "id": "service-reload",
    "name": "service-reload",
    "api": "/api/mock2/number/random",
    "body": "现在是：${random}, 当前时间：${date}"
  }
]
```

### rebuild

重新构建，基于 args 传参和 schemaApi 绑定变量，让 service 获取不同的 schema。

```
/* Detailed source-code truncated for AI context efficiency. */
```

### setValue

通过`setValue`更新指定 Service 的数据。

#### 合并数据

默认`setValue`会将新数据与目标组件数据进行合并。

```schema: scope="body"
[
    {
      "type": "button",
      "label": "更新数据",
      "onEvent": {
        "click": {
          "actions": [
            {
              "actionType": "setValue",
              "componentId": "service-setvalue",
              "args": {
                "value": {
                  "name": "aisuda",
                  "email": "aisuda@baidu.com"
                }
              }
            }
          ]
        }
      }
    },
    {
      "type": "service",
      "id": "service-setvalue",
      "name": "service-setvalue",
      "data": {
        "name": "amis",
        "email": "amis@baidu.com"
      },
      "body": [
        {
          "type": "tpl",
          "tpl": "名字：${name|default:'-'}，邮箱：${email|default:'-'}"
        }
      ]
    }
]
```

#### 覆盖数据

可以通过`"dataMergeMode": "override"`来覆盖目标组件数据。

```schema: scope="body"
[
    {
      "type": "button",
      "label": "更新数据",
      "onEvent": {
        "click": {
          "actions": [
            {
              "actionType": "setValue",
              "componentId": "service-setvalue",
              "args": {
                "value": {
                  "name": "aisuda"
                }
              },
              "dataMergeMode": "override"
            }
          ]
        }
      }
    },
    {
      "type": "service",
      "id": "service-setvalue",
      "name": "service-setvalue",
      "data": {
        "name": "amis",
        "email": "amis@baidu.com"
      },
      "body": [
        {
          "type": "tpl",
          "tpl": "名字：${name|default:'-'}，邮箱：${email|default:'-'}"
        }
      ]
    }
]
```

---

### Zh CN Components Shape (`docs/zh-CN/components/shape.md`)

---
title: Shape 形状
description:
type: 0
group: ⚙ 组件
menuName: Tabs
icon:
---

用于展示形状

## 基本用法

```schema
{
    type: "page",
    body: [
      {
        type: 'shape',
        className: 'm-2',
        shapeType: 'triangle'
      },
      {
        type: 'shape',
        className: 'm-2',
        shapeType: 'square'
      },
      {
        type: 'shape',
        className: 'm-2',
        shapeType: 'pentagon'
      },
      {
        type: 'shape',
        className: 'm-2',
        shapeType: 'star'
      }
    ]
}
```

## 配置大小

```schema
{
    type: "page",
    body: [
      {
        type: 'shape',
        className: 'm-2',
        shapeType: 'triangle',
        width: 200,
        height: 100
      },
      {
        type: 'shape',
        className: 'm-2',
        shapeType: 'square',
        height: 100
      },
      {
        type: 'shape',
        className: 'm-2',
        shapeType: 'pentagon',
        width: 100,
        height: 100
      }
    ]
}
```

## 配置圆角

```schema
{
    type: "page",
    body: [
      {
        type: 'shape',
        className: 'm-2',
        shapeType: 'triangle',
        radius: 4
      },
      {
        type: 'shape',
        className: 'm-2',
        shapeType: 'square',
        radius: -4
      },
      {
        type: 'shape',
        className: 'm-2',
        shapeType: 'pentagon',
        radius: 4
      }
    ]
}
```

## 配置边框

```schema
{
    type: "page",
    body: [
      {
        type: 'shape',
        className: 'm-2',
        shapeType: 'triangle',
        width: 100,
        height: 100,
        color: '#eee',
        stroke: '#000',
        strokeWidth: 4,
        strokeType: 'line',
      },
      {
        type: 'shape',
        className: 'm-2',
        shapeType: 'square',
        width: 100,
        height: 100,
        color: '#eee',
        stroke: '#000',
        strokeWidth: 4,
        strokeType: 'dash',
      },
      {
        type: 'shape',
        className: 'm-2',
        shapeType: 'pentagon',
        width: 100,
        height: 100,
        color: '#eee',
        stroke: '#000',
        strokeWidth: 4,
        strokeType: 'dot',
      },
      {
        type: 'shape',
        className: 'm-2',
        shapeType: 'star',
        width: 100,
        height: 100,
        color: '#eee',
        stroke: '#000',
        strokeWidth: 4,
        strokeType: 'dot',
      }
    ]
}
```

## 配置颜色

```schema
{
    type: "page",
    body: [
      {
        type: 'shape',
        className: 'm-2',
        shapeType: 'triangle',
        color: '#2468f2',
        radius: 4
      },
      {
        type: 'shape',
        className: 'm-2',
        shapeType: 'heart',
        color: '#f23d3d'
      }
    ]
}
```

## 自定义路径

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 更多图形

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 事件表

> 2.6.1 及以上版本

当前组件会对外派发以下事件，可以通过`onEvent`来监听这些事件，并通过`actions`来配置执行的动作，详细查看[事件动作](../../docs/concepts/event-action)。

| 事件名称 | 事件参数                     | 说明         |
| -------- | ---------------------------- | ------------ |
| click    | `label: string` 鼠标事件对象 | `点击`时触发 |

### click

鼠标点击。

```schema: scope="body"
 {
  type: 'shape',
  className: 'm-2',
  shapeType: 'triangle',
  "width": 100,
  "height": 100,
  onEvent: {
    click: {
      actions: [
        {
          actionType: 'toast',
          args: {
            msgType: 'info',
            msg: '派发点击事件'
          }
        }
      ]
    }
  }
}
```

## 属性表

| 属性名    | 类型         | 默认值    | 说明                  |
| --------- | ------------ | --------- | --------------------- |
| type      | `string`     | `'shape'` | 指定为图形渲染器      |
| shapeType | `IShapeType` | `'-'`     | 图形类型              |
| className | `string`     |           | 自定义 CSS 样式类名   |
| color     | `string`     |           | 填充颜色              |
| width     | `number`     | `200`     | 图形宽度              |
| height    | `number`     | `200`     | 图形大小              |
| radius    | `number`     | `0`       | 圆角大小,负数表示内弧 |

---

### Zh CN Components Slider (`docs/zh-CN/components/slider.md`)

---
title: Slider 滑动条
description:
type: 0
group: ⚙ 组件
menuName: Tabs
icon:
---

主要用于移动端中支持左右滑动展示更多内容，在桌面端中更多内容展示在右侧

## 基本用法

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 事件表

> 2.6.1 及以上版本

当前组件会对外派发以下事件，可以通过`onEvent`来监听这些事件，并通过`actions`来配置执行的动作，详细查看[事件动作](../../docs/concepts/event-action)。

| 事件名称  | 事件参数                     | 说明               |
| --------- | ---------------------------- | ------------------ |
| leftShow  | `label: string` 鼠标事件对象 | 左侧内容出现时触发 |
| leftHide  | `label: string` 鼠标事件对象 | 左侧内容隐藏时触发 |
| rightShow | `label: string` 鼠标事件对象 | 右侧内容出现时触发 |
| rightHide | `label: string` 鼠标事件对象 | 右侧内容隐藏时触发 |

## 属性表

| 属性名    | 类型                                      | 默认值     | 说明                                      |
| --------- | ----------------------------------------- | ---------- | ----------------------------------------- |
| type      | `string`                                  | `'slider'` | 指定为滑动条渲染器                        |
| body      | [SchemaNode](../../docs/types/schemanode) |            | 容器主要内容                              |
| right     | [SchemaNode](../../docs/types/schemanode) |            | 容器右侧内容，在 pc 下展示在右侧          |
| left      | [SchemaNode](../../docs/types/schemanode) |            | 容器左侧内容，在 pc 下展示在右侧          |
| bodyWidth | `string`                                  | `'60%'`    | pc 下 body 即移动端默认宽度占比，默认 60% |

---

### Zh CN Components Sparkline (`docs/zh-CN/components/sparkline.md`)

---
title: Sparkline 走势图
description:
type: 0
group: ⚙ 组件
menuName: SparkLine
icon:
order: 63
---

简单走势图，只做简单的展示，详细展示请采用 Chart 来完成。

## 基本使用

配置类型，然后设置值即可，值为数组格式。

当前例子为静态值，通常你会需要配置成 `name` 与当前环境数据关联。

```schema
{
    "type": "page",
    "body": {
        "type": "sparkline",
        "height": 30,
        "value": [3, 5, 2, 4, 1, 8, 3, 7]
    }
}
```

## 点击行为

可以通过配置`"clickAction": {}`，来指定图表节点的点击行为，支持 amis 的 [行为](./action)。

```schema
{
    "type": "page",
    "body": {
        "type": "sparkline",
        "value": [3, 5, 2, 4, 1, 8, 3, 7],
        "clickAction": {
          "actionType": "dialog",
          "dialog": {
            "title": "走势详情",
            "body": "这里你可以放个 chart 来展示详情。"
          }
        }
    }
}
```

## 空数据显示

> 1.4.2 及以上版本

通过 `placeholder` 可以设置空数据时显示的内容

```schema
{
    "type": "page",
    "body": {
        "type": "sparkline",
        "value": [],
        "placeholder": "无数据"
    }
}
```

## 属性表

| 属性名      | 类型     | 默认值 | 说明                 |
| ----------- | -------- | ------ | -------------------- |
| name        | `string` |        | 关联的变量           |
| width       | `number` |        | 宽度                 |
| height      | `number` |        | 高度                 |
| placeholder | `string` |        | 数据为空时显示的内容 |

---

### Zh CN Components Spinner (`docs/zh-CN/components/spinner.md`)

---
title: Spinner 加载中
description:
type: 0
group: ⚙ 组件
menuName: Spinner
icon:
order: 64
---

一般用来做 `loading` 使用。

## 基本使用

`show` 属性控制 `spinner` 是否渲染。

```schema
{
    "type": "page",
    "body": {
        "type": "spinner",
        "show": true,
    }
}
```

`size` 属性控制 `spinner` 的大小，有三种配置：`sm`, `lg` 和 空值。

```schema
{
    "type": "page",
    "body": [
        {
            "type": "spinner",
            "show": true,
            "size": "sm",
            "className": "mr-4"
        },
        {
            "type": "spinner",
            "show": true,
            "size": "",
            "className": "mr-4"
        },
        {
            "type": "spinner",
            "show": true,
            "size": "lg"
        }
    ]
}
```

`className` 属性、 `spinnerClassName`属性和 `spinnerWrapClassName`属性可以配置 spinner 自定义的 class，`className`会添加到 spinner 组件的最外层标签上，`spinnerClassName`会添加到 icon 对应的标签上，`spinnerWrapClassName` 在作为组件容器使用时，会作用于整个 Spinner 组件的最外层元素上。

```schema
{
    "type": "page",
    "body": [
        {
            "type": "spinner",
            "show": true,
            "className": "my-spinner",
            "spinnerClassName": "my-spinner-custom-icon",
            "spinnerWrapClassName": "my-spinner-wrap",
        }
    ]
}
```

`icon` 属性可以配置自定义的图标，可以是 `amis` 内置的图标名称（需要是在 icons.tsx 组件中注册过的）; 可以是字体图标库的名称(需要引入对应的图标库)，比如`fa fa-spinner`; 也可以是网络图片，比如 `/examples/static/logo.png`;

```schema
{
    "type": "page",
    "body": [
        {
            "type": "spinner",
            "show": true,
            "icon": "",
            "className": "mr-4"
        },
        {
            "type": "spinner",
            "show": true,
            "icon": "reload",
            "className": "mr-4"
        },
        {
            "type": "spinner",
            "show": true,
            "icon": "fa fa-spinner",
            "className": "mr-4"
        },
        {
            "type": "spinner",
            "show": true,
            "icon": "/examples/static/logo.png"
        }
    ]
}
```

`tip` 属性可以配置 spinner 的文案，同时 `tipPlacement`可以配置 tip 的相对于 icon 的位置，有四种配置：`top`,`right`,`bottom`(默认),`left`;

```schema
{
    "type": "page",
    "body": [
        {
            "type": "spinner",
            "show": true,
            "tip": "加载中...",
            "className": "mr-10"
        },
        {
            "type": "spinner",
            "show": true,
            "tip": "加载中...",
            "tipPlacement": "right",
            "className": "mr-10"
        },
        {
            "type": "spinner",
            "show": true,
            "tip": "加载中...",
            "tipPlacement": "top",
            "className": "mr-10"
        },
        {
            "type": "spinner",
            "show": true,
            "tip": "加载中...",
            "tipPlacement": "left"
        }
    ]
}
```

`delay` 属性可以配置 spinner 的延迟显示时间，例如 delay=1000，`show` 属性设为 `true` 后，1000ms 后才会显示出来。

```schema
{
    "type": "page",
    "body": {
        "type": "spinner",
        "show": true,
        "delay": 1000
    }
}
```

## 作为容器使用

`spinner` 组件可以作为容器使用，被包裹的内容可通过 `body` 配置, 且作为容器使用的时候可以使用 `overlay` 属性来配置显示 spinner 的时候是否显示遮罩层（遮罩层背景颜色默认是透明的，可通过外层 className 自定义遮罩层颜色）。

```schema
{
    "type": "page",
    "body": {
        "type": "spinner",
        "show": true,
        "overlay": true,
        "body": {
            "type": "form",
            "body": [
                {
                    "type": "input-text",
                    "name": "name",
                    "label": "姓名："
                },
                {
                    "name": "email",
                    "type": "input-email",
                    "label": "邮箱："
                }
            ]
        }
    }
}
```

## Spinner 在组件树中的默认表现

当在一棵树中，父组件和子组件同时在 `loading` 状态时，只有父组件的 `loading` 会生效；父组件的 `loading` 结束后才会根据子组件中的`loading`状态，来决定子组件中的`Spinner`是否需要进入`loading`。

```schema
{
type: 'service',
api: '/api/mock2/sample?orderBy=id&orderDir=desc&perPage=10&waitSeconds=5',
body: {
 type: 'page',
 initApi:
   '/api/mock2/sample?orderBy=id&orderDir=desc&perPage=10&waitSeconds=10',
 }
}
```

在这个例子中，`service` 会先进入 `loading` ，5 秒后 `page` 组件开始 `loading`

## 动态控制组件渲染

使用 `showOn` 表达式控制 `spinner` 是否渲染。

```schema
{
  type: 'page',
  body: {
    type: 'form',
    body: [
      {
        type: 'switch',
        name: 'show',
        label: 'show',
        value: true
      },
      {
        type: 'spinner',
        overlay: false,
        showOn: 'this.show'
      }
    ]
  }
}
```

## 属性表

| 属性名               | 类型                                        | 默认值    | 说明                                                                                                                                                                                     |
| -------------------- | ------------------------------------------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| type                 | `string`                                    | `spinner` | 指定为 Spinner 渲染器                                                                                                                                                                    |
| show                 | `boolean`                                   | `true`    | 是否显示 spinner 组件                                                                                                                                                                    |
| showOn               | [表达式](../../../docs/concepts/expression) | `true`    | 是否显示 spinner 组件的条件                                                                                                                                                              |
| className            | `string`                                    |           | spinner 图标父级标签的自定义 class                                                                                                                                                       |
| spinnerClassName     | `string`                                    |           | 组件中 icon 所在标签的自定义 class                                                                                                                                                       |
| spinnerWrapClassName | `string`                                    |           | 作为容器使用时组件最外层标签的自定义 class                                                                                                                                               |
| size                 | `string`                                    |           | 组件大小 `sm` `lg`                                                                                                                                                                       |
| icon                 | `string`                                    |           | 组件图标，可以是`amis`内置图标，也可以是字体图标或者网络图片链接，作为 ui 库使用时也可以是自定义组件                                                                                     |
| tip                  | `string`                                    |           | 配置组件文案，例如`加载中...`                                                                                                                                                            |
| tipPlacement         | `top`, `right`, `bottom`, `left`            | `bottom`  | 配置组件 `tip` 相对于 `icon` 的位置                                                                                                                                                      |
| delay                | `number`                                    | `0`       | 配置组件显示延迟的时间（毫秒）                                                                                                                                                           |
| overlay              | `boolean`                                   | `true`    | 配置组件显示 spinner 时是否显示遮罩层                                                                                                                                                    |
| body                 | [SchemaNode](../../docs/types/schemanode)   |           | 作为容器使用时，被包裹的内容                                                                                                                                                             |
| loadingConfig        | `{root?: string}`                           |           | 为 `Spinner` 指定挂载的容器, `root` 是一个 selector，在拥有`Spinner`的组件上都可以通过传递`loadingConfig`改变 Spinner 的挂载位置，开启后，会强制开启属性`overlay=true`，并且`icon`会失效 |

---

### Zh CN Components Status (`docs/zh-CN/components/status.md`)

---
title: Status 状态
description:
type: 0
group: ⚙ 组件
menuName: Status
icon:
order: 65
---

## 基本用法

它最适合的用法是放在列表类组件（CRUD，Table，List 等）的列中，用来表示状态。

```schema: scope="body"
{
    "type": "status",
    "value": 1
}
```

## 默认状态列表

下表是默认支持的几种状态：

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 自定义状态图标、文本、颜色

> 2.8.0 及 以上版本

如果默认提供的状态无法满足业务需求，可使用`source`自定义状态, 如下：

```json
{
  "type": "status",
  "source": {
    "normal": {
      "label": "正常",
      "icon": "fa fa-times-circle",
      "color": "#000"
    },
    "unusual": {
      "label": "异常",
      "icon": "fa fa-times-circle",
      "color": "#f00"
    }
  },
  "value": "normal"
}
```

`source`配置类似于`mapping`映射，不同的`key`值匹配渲染不同状态，支持以下属性：

| 属性名    | 类型     | 说明                   |
| --------- | -------- | ---------------------- |
| label     | `string` | 显示文本               |
| icon      | `string` | 图标, 例如`fa fa-plus` |
| color     | `string` | 状态颜色               |
| className | `string` | 状态的 独立 CSS 类名   |

注意：自定义状态会和默认状态合并。

```schema
{
  "type": "page",
  "body": [
    {
      "type": "status",
      "source": {
        "0": {
          "label": "正常",
          "icon": "fa fa-times-circle",
          "color": "#000"
        },
        "1": {
          "label": "异常",
          "icon": "fa fa-times-circle",
          "color": "#f00"
        }
      },
      "value": 0
    }
  ]
}
```

`source` 属性也支持[数据映射](../../docs/concepts/data-mapping)，通过变量获取上下文中的变量

```schema
{
  "type": "page",
  "data": {
    "mysource": {
      "0": {
        "label": "正常",
        "icon": "fa fa-times-circle",
        "color": "#000"
      },
      "1": {
        "label": "异常",
        "icon": "fa fa-times-circle",
        "color": "#f00"
      }
    }
  },
  "body": [
    {
      "type": "status",
      "source": "${mysource}",
      "className": "mr-4",
      "value": 0
    },
    {
      "type": "status",
      "source": "${mysource}",
      "value": 1
    }
  ]
}
```

## 自定义状态图标和文本

> 推荐使用新属性`source`配置

> 如果默认提供的状态无法满足业务需求，可以使用`map` 和 `labelMap`属性分别配置状态组件的**图标**和**展示文案**。用户自定义的`map` 和 `labelMap`会和默认属性进行 merge，如果只需要修改某一项配置时，无需全量覆盖。

```schema
{
  "type": "page",
  "body": [
    {
      "type": "status",
      "map": {
        "0": "fa fa-check-circle",
        "1": "fa fa-times-circle"
      },
      "labelMap": {
        "0": "正常",
        "1": "异常"
      },
      "value": 0,
      "className": "mr-3"
    },
    {
      "type": "status",
      "map": {
        "0": "fas fa-check-circle",
        "1": "fas fa-times-circle"
      },
      "labelMap": {
        "0": "正常",
        "1": "异常"
      },
      "value": 1
    }
  ]
}
```

## 动态数据

> 推荐使用新属性`source`配置

> 2.3.0 及以上版本

`map` 和 `labelMap`支持配置变量，通过数据映射获取上下文中的变量。

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 属性表

| 属性名           | 类型     | 默认值 | 版本  | 说明                                                             |
| ---------------- | -------- | ------ | ----- | ---------------------------------------------------------------- |
| type             | `string` |        |       | `"status"` 指定为 Status 渲染器                                  |
| className        | `string` |        |       | 外层 Dom 的 CSS 类名                                             |
| placeholder      | `string` | `-`    |       | 占位文本                                                         |
| map              | `object` |        | 2.3.0 | 映射图标                                                         |
| labelMap         | `object` |        | 2.3.0 | 映射文本                                                         |
| source           | `object` |        | 2.8.0 | 自定义映射状态，支持[数据映射](../../docs/concepts/data-mapping) |
| source.label     | `string` |        | 2.8.0 | 映射文本                                                         |
| source.icon      | `string` |        | 2.8.0 | 映射图标                                                         |
| source.color     | `string` |        | 2.8.0 | 映射状态颜色                                                     |
| source.className | `string` |        | 2.8.0 | 映射状态的 独立 CSS 类名                                         |

---

### Zh CN Components Steps (`docs/zh-CN/components/steps.md`)

---
title: Steps 步骤条
description:
type: 0
group: ⚙ 组件
menuName: Steps
icon:
order: 68
---

步骤条组件

## 基本用法

```schema
{
  "type": "page",
  "body": [
    {
      "type": "steps",
      "value": 1,
      "steps": [
        {
          "title": "First",
          "subTitle": "this is subTitle",
          "description": "this is description"
        },
        {
          "title": "Second"
        },
        {
          "title": "Last"
        }
      ]
    }
  ]
}
```

## 设置状态

```schema
{
  "type": "page",
  "body": {
    "type": "steps",
    "value": 1,
    "status": "error",
    "steps": [
      {
        "title": "First"
      },
      {
        "title": "Second",
        "subTitle": "this is subTitle",
        "description": "this is description"
      },
      {
        "title": "Last"
      }
    ]
  }
}
```

## 指定步骤条方向

```schema
{
  "type": "page",
  "body": {
    "type": "steps",
    "mode": 'vertical',
    "value": 1,
    "steps": [
      {
        "title": "First",
        "subTitle": "this is subTitle",
        "description": "this is description"
      },
      {
        "title": "Second",
        "subTitle": "this is subTitle",
        "description": "this is description"
      },
      {
        "title": "Last",
        "subTitle": "this is subTitle",
        "description": "this is description"
      }
    ]
  }
}
```

## 指定标签放置位置

```schema
{
  "type": "page",
  "body": {
    "type": "steps",
    "value": 1,
    "labelPlacement": "vertical",
    "steps": [
      {
        "title": "First",
        "subTitle": "this is subTitle",
        "description": "this is description"
      },
      {
        "title": "Second",
        "subTitle": "this is subTitle",
        "description": "this is description"
      },
      {
        "title": "Last",
        "subTitle": "this is subTitle",
        "description": "this is description"
      }
    ]
  }
}
```

## 点状步骤条

```schema
{
  "type": "page",
  "body": {
    "type": "steps",
    "value": 1,
    "progressDot": true,
    "steps": [
      {
        "title": "First",
        "subTitle": "this is subTitle",
        "description": "this is description"
      },
      {
        "title": "Second",
        "subTitle": "this is subTitle",
        "description": "this is description"
      },
      {
        "title": "Last",
        "subTitle": "this is subTitle",
        "description": "this is description"
      }
    ]
  }
}
```

## 简单模式

```schema
{
  "type": "page",
  "body": [
    {
      "type": "steps",
      "value": 1,
      "mode": "simple",
      "steps": [
        {
          "title": "First"
        },
        {
          "title": "Second"
        },
        {
          "title": "Last"
        }
      ]
    }
  ]
}
```

## 数据映射

当前处于第几步统一通过 `name` 关联变量名，其他配置可通过 `"${xxx}"` 关联上下文变量。

```schema
{
  "type": "page",
  "data": {
    "step": 1,
    "status": "error",
    "secondTitle": "Second"
  },
  "body": [
    {
      "type": "steps",
      "name": "step",
      "status": "${status}",
      "steps": [
        {
          "title": "First",
          "subTitle": "this is subTitle",
          "description": "this is description"
        },
        {
          "title": "${secondTitle}"
        },
        {
          "title": "Last"
        }
      ]
    }
  ]
}
```

## 接口映射

接口返回的数据也是一样，都会在同一个数据域，所以取值方式是一样的。

```schema
{
  "type": "page",
  "initApi": "/api/mock2/steps/get",
  "body": [
    {
      "type": "steps",
      "name": "step",
      "status": "${status}",
      "steps": [
        {
          "title": "First",
          "subTitle": "this is subTitle",
          "description": "this is description"
        },
        {
          "title": "Secord"
        },
        {
          "title": "Last"
        }
      ]
    }
  ]
}
```

## Form 中静态展示

```schema
{
  "type": "page",
  "body": {
    "type": "form",
    "initApi": "/api/mock2/steps/steps",
    "body": [
      {
        "type": "steps",
        "source": "${steps}",
        "name": "current"
      }
    ]
  }
}
```

## 动态数据

### 远程拉取

除了可以通过数据映射获取当前数据域中的变量以外，source 还支持配置接口，格式为 API，用于动态返回选项组。

```schema
{
  "type": "page",
  "body": {
    "type": "form",
    "body": [
      {
        "type": "steps",
        "name": "steps",
        "source": "/api/mock2/steps/steps"
      }
    ]
  }
}
```

远程拉取接口时，返回的数据结构除了需要满足 amis 接口要求的基本数据结构 以外，必须用"steps"作为选项组的 key 值，如下：

```json
{
  "status": 0,
  "msg": "",
  "data": {
    "steps": [
      {
        "title": "First",
        "subTitle": "this is sub title",
        "value": "first"
      },
      {
        "title": "Secord",
        "description": "this is description",
        "value": "secord"
      },
      {
        "title": "Last",
        "value": "last"
      }
    ],
    "value": "secord",
    "status": "error"
  }
}
```

### 数据域变量配置

> 1.9.1 及以上版本

```schema
{
  "type": "page",
  "data": {
    "steps": [
      {
        "title": "First",
        "subTitle": "this is subTitle",
        "description": "this is description"
      },
      {
        "title": "Second"
      },
      {
        "title": "Last"
      }
    ]
  },
  "body": [
    {
      "type": "steps",
      "name": "step",
      "source": "${steps}"
    }
  ]
}
```

## 自定义不同步骤以及状态

```schema
{
  "type": "page",
  "body": {
    "type": "steps",
    "value": "b",
    "status": {
      "a": "finish",
      "b": "error",
      "c": "wait"
    },
    "steps": [
      {
        "title": "First",
        "value": "a"
      },
      {
        "title": "Second",
        "subTitle": "this is subTitle",
        "description": "this is description",
        "value": "b"
      },
      {
        "title": "Third",
        "value": "c"
      }
    ]
  }
}
```

## 属性表

| 属性名         | 类型                                                                              | 默认值       | 说明                                                                             |
| -------------- | --------------------------------------------------------------------------------- | ------------ | -------------------------------------------------------------------------------- |
| type           | `string`                                                                          |              | `"steps"` 指定为 步骤条 渲染器                                                   |
| steps          | Array<[step](#step)>                                                              | []           | 数组，配置步骤信息                                                               |
| source         | [API](../../../docs/types/api) 或 [数据映射](../../../docs/concepts/data-mapping) |              | 选项组源，可通过数据映射获取当前数据域变量、或者配置 API 对象                    |
| name           | `string`                                                                          |              | 关联上下文变量                                                                   |
| value          | `string` \| `number`                                                              | `-`          | 设置默认值，注意不支持表达式                                                     |
| status         | [StepStatus](#StepStatus) \| {[propName: string]: stepStatus;}                    | `-`          | 状态                                                                             |
| className      | `string`                                                                          | `-`          | 自定义类名                                                                       |
| mode           | `horizontal` \| `vertical` \| `simple`                                            | `horizontal` | 指定步骤条模式。目前支持水平（horizontal）、竖直（vertical）和简单（simple）模式 |
| labelPlacement | `horizontal` \| `vertical`                                                        | `horizontal` | 指定标签放置位置，默认水平放图标右侧，可选 (vertical) 放图标下方                 |
| progressDot    | `boolean`                                                                         | `false`      | 点状步骤条                                                                       |

### step

| 属性名      | 类型                                                  | 默认值 | 说明                                    |
| ----------- | ----------------------------------------------------- | ------ | --------------------------------------- |
| title       | `string` \| [SchemaNode](../../docs/types/schemanode) |        | 标题                                    |
| subTitle    | `string` \| [SchemaNode](../../docs/types/schemanode) |        | 子标题                                  |
| description | `string` \| [SchemaNode](../../docs/types/schemanode) |        | 详细描述                                |
| icon        | `string`                                              |        | icon 名，支持 fontawesome v4 或使用 url |
| value       | `string`                                              |        | value                                   |
| className   | `string`                                              |        | 自定义类名                              |

### StepStatus

`wait` | `process` | `finish` | `error`

---

### Zh CN Components Switch Container (`docs/zh-CN/components/switch-container.md`)

---
title: switch-container 状态容器
description:
type: 0
group: ⚙ 组件
menuName: switch-container 容器
icon:
order: 50
---

switch-container 是一种特殊的容器组件，它可以根据动态数据显示条件渲染组件的某一状态。注意容器只会显示最多一种状态，只显示首个命中的状态。容器的不同状态是对应的展示配置，可通过组件搭配与嵌套设计任意展示样式。状态容器的外观与事件动作与容器组件类似，支持常见的外观设置与点击、移入、移出事件动作。

状态容器主要用于编辑器内统一管理复杂组件的多种状态，同时避免因为组件多状态显示而干扰设计。如果只使用 amis 引擎，也可以直接用容器加显示条件实现。

## 基本用法

```schema: scope="body"
{
  "type": "form",
  "title": "",
  "mode": "horizontal",
  "dsType": "api",
  "feat": "Insert",
  "body": [
    {
      "type": "button-group-select",
      "name": "state",
      "label": "切换状态",
      "inline": false,
      "options": [
        {
          "label": "选项1",
          "value": "a"
        },
        {
          "label": "选项2",
          "value": "b"
        }
      ],
      "multiple": false,
      "value": ""
    },
    {
      "type": "switch-container",
      "items": [
        {
          "title": "状态1",
          "body": [
            {
              "type": "tpl",
              "tpl": "状态内容1",
              "wrapperComponent": "",
              "inline": false
            }
          ],
          "visibleOn": "${state == \"a\"}"
        },
        {
          "title": "状态2",
          "body": [
            {
              "type": "tpl",
              "tpl": "状态内容2",
              "wrapperComponent": "",
              "inline": false
            }
          ],
          "visibleOn": "${state == \"b\"}"
        }
      ],
      "style": {
        "position": "static",
        "display": "block"
      }
    }
  ],
  "actions": [],
  "resetAfterSubmit": true
}
```

### style

container 可以通过 style 来设置样式，比如背景色或背景图，注意这里的属性是使用驼峰写法，是 `backgroundColor` 而不是 `background-color`。

```schema: scope="body"
{
  "type": "switch-container",
  "style": {
      "backgroundColor": "#C4C4C4"
  },
  "items": [
    {
      "title": "状态1",
      "body": [
        {
          "type": "tpl",
          "tpl": "状态内容1",
          "wrapperComponent": "",
          "inline": false
        }
      ]
    }
  ],
}
```

## 属性表

| 属性名    | 类型                                      | 默认值        | 说明                    |
| --------- | ----------------------------------------- | ------------- | ----------------------- |
| type      | `string`                                  | `"container"` | 指定为 container 渲染器 |
| className | `string`                                  |               | 外层 Dom 的类名         |
| style     | `Object`                                  |               | 自定义样式              |
| items     | [SchemaNode](../../docs/types/schemanode) |               | 容器内容                |

## 事件表

> 3.3.0 及以上版本

当前组件会对外派发以下事件，可以通过`onEvent`来监听这些事件，并通过`actions`来配置执行的动作，在`actions`中可以通过`${事件参数名}`或`${event.data.[事件参数名]}`来获取事件产生的数据，详细查看[事件动作](../../docs/concepts/event-action)。

| 事件名称   | 事件参数 | 说明           |
| ---------- | -------- | -------------- |
| click      | -        | 点击时触发     |
| mouseenter | -        | 鼠标移入时触发 |
| mouseleave | -        | 鼠标移出时触发 |

### click

鼠标点击。可以尝试通过`${event.context.nativeEvent}`获取鼠标事件对象。

```schema: scope="body"
{
    "type": "switch-container",
    "items": [
      {
        "title": "状态1",
        "body": [
          {
            "type": "tpl",
            "tpl": "状态内容1",
            "wrapperComponent": "",
            "inline": false
          }
        ]
      }
    ],
    "onEvent": {
        "click": {
            "actions": [
                {
                    "actionType": "toast",
                    "args": {
                        "msgType": "info",
                        "msg": "${event.context.nativeEvent.type}"
                    }
                }
            ]
        }
    }
}
```

### mouseenter

鼠标移入。可以尝试通过`${event.context.nativeEvent}`获取鼠标事件对象。

```schema: scope="body"
{
    "type": "switch-container",
    "items": [
      {
        "title": "状态1",
        "body": [
          {
            "type": "tpl",
            "tpl": "状态内容1",
            "wrapperComponent": "",
            "inline": false
          }
        ]
      }
    ],
    "onEvent": {
        "mouseenter": {
            "actions": [
                {
                    "actionType": "toast",
                    "args": {
                        "msgType": "info",
                        "msg": "${event.context.nativeEvent.type}"
                    }
                }
            ]
        }
    }
}
```

### mouseleave

鼠标移出。可以尝试通过`${event.context.nativeEvent}`获取鼠标事件对象。

```schema: scope="body"
{
    "type": "switch-container",
    "items": [
      {
        "title": "状态1",
        "body": [
          {
            "type": "tpl",
            "tpl": "状态内容1",
            "wrapperComponent": "",
            "inline": false
          }
        ]
      }
    ],
    "onEvent": {
        "mouseleave": {
            "actions": [
                {
                    "actionType": "toast",
                    "args": {
                        "msgType": "info",
                        "msg": "${event.context.nativeEvent.type}"
                    }
                }
            ]
        }
    }
}
```

---

### Zh CN Components Table View (`docs/zh-CN/components/table-view.md`)

---
title: Table View 表格展现
description:
type: 0
group: ⚙ 组件
menuName: Table View 表格展现
icon:
order: 68
---

> 1.2.0 及以上版本才有此功能

通过表格的方式来展现数据，和 [table](./table) 的不同之处：

- 数据源要求不同
  - table 的数据源需要是多行的数据，最典型的就是来自某个数据库的表
  - table view 的数据源可以来自各种固定的数据，比如单元格的某一列是来自某个变量
- 功能不同
  - table 只能用来做数据表的展现
  - table view 除了展现复杂的报表，还能用来进行布局
- 合并单元格方式不同
  - table 的合并单元格需要依赖数据
  - table view 的合并单元格是手动指定的，因此可以支持不规则的数据格式

## 基本用法

```schema: scope="body"
{
  "type": "service",
  "data": {
    "beijing": "20",
    "tianjing": "19"
  },
  "body": [
    {
      "type": "table-view",
      "trs": [
        {
          "background": "#F7F7F7",
          "tds": [
            {
              "body": {
                "type": "tpl",
                "tpl": "地区"
              }
            },
            {
              "body": {
                "type": "tpl",
                "tpl": "城市"
              }
            },
            {
              "body": {
                "type": "tpl",
                "tpl": "销量"
              }
            }
          ]
        },
        {
          "tds": [
            {
              "rowspan": 2,
              "body": {
                "type": "tpl",
                "tpl": "华北"
              }
            },
            {
              "body": {
                "type": "tpl",
                "tpl": "北京"
              }
            },
            {
              "body": {
                "type": "tpl",
                "tpl": "${beijing}"
              }
            }
          ]
        },
        {
          "tds": [
            {
              "body": {
                "type": "tpl",
                "tpl": "天津"
              }
            },
            {
              "body": {
                "type": "tpl",
                "tpl": "${tianjing}"
              }
            }
          ]
        }
      ]
    }
  ]
}
```

可以看到 table view 需要手动进行单元格合并，因此更适合使用可视化编辑器进行编辑。

## 设置项

table view 的设置项有三层，可以分别对表格级别、行级别、单元格级别进行设置。

### 表格设置项

| 属性名      | 类型            | 默认值                                                | 说明             |
| ----------- | --------------- | ----------------------------------------------------- | ---------------- |
| width       | `number/string` | '100%'                                                |                  |
| padding     | `number/string` | 'var(--TableCell-paddingY) var(--TableCell-paddingX)' | 单元格默认内间距 |
| border      | `boolean`       | true                                                  | 是否显示边框     |
| borderColor | `string`        | `var(--borderColor)`                                  | 边框颜色         |
| trs         |                 |                                                       | 参考下面的行设置 |

### 行设置

| 属性名     | 类型            | 默认值 | 说明                 |
| ---------- | --------------- | ------ | -------------------- |
| height     | `number/string` |        |                      |
| background | `string`        |        | 行背景色             |
| tds        |                 |        | 参考下面的单元格设置 |

### 单元格设置

| 属性名     | 类型                                      | 默认值         | 说明                                                             |
| ---------- | ----------------------------------------- | -------------- | ---------------------------------------------------------------- |
| background | `string`                                  |                | 单元格背景色                                                     |
| color      | `string`                                  |                | 单元格文字颜色                                                   |
| bold       | `boolean`                                 | false          | 单元格文字是否加粗                                               |
| width      | `number/string`                           |                | 单元格宽度，只需要设置第一行                                     |
| padding    | `number/string`                           | 集成表格的设置 | 单元格内间距                                                     |
| align      | `string`                                  | `left`         | 单元格内的水平对齐，可以是 `left`、`center`、`right`             |
| valign     | `string`                                  | `middle`       | 单元格内的垂直对齐，可以是 `top`、`middle`、`bottom`、`baseline` |
| colspan    | `number`                                  |                | 单元格水平跨几行                                                 |
| rowspan    | `number`                                  |                | 单元格垂直跨几列                                                 |
| body       | [SchemaNode](../../docs/types/schemanode) |                | 其它 amis 设置                                                   |

#### 单元格样式示例

比如将其它两列的单元格边框设置为 0，就能实现特殊的展现效果

```schema: scope="body"
{
  "type": "table-view",
  "trs": [
    {
      "background": "#F7F7F7",
      "tds": [
        {
          "body": {
            "type": "tpl",
            "tpl": "地区"
          }
        },
        {
          "body": {
            "type": "tpl",
            "tpl": "城市"
          }
        },
        {
          "body": {
            "type": "tpl",
            "tpl": "销量"
          }
        }
      ]
    },
    {
      "tds": [
        {
          "body": {
            "type": "tpl",
            "tpl": ""
          },
          "style": {
            "borderBottomWidth": 0,
            "borderLeftWidth": 0
          }
        },
        {
          "body": {
            "type": "tpl",
            "tpl": "北京"
          }
        },
        {
          "body": {
            "type": "tpl",
            "tpl": ""
          },
          "style": {
            "borderBottomWidth": 0,
            "borderRightWidth": 0
          }
        }
      ]
    }
  ]
}
```

### 列设置项

列设置项主要是用于控制整列的样式，比如

```schema: scope="body"
{
  "type": "table-view",
  "cols": [
    {

    },
    {
      "style": {
        "background": "#F7F7F7"
      }
    }
  ],
  "trs": [
    {
      "tds": [
        {
          "rowspan": 2,
          "body": {
            "type": "tpl",
            "tpl": "华北"
          }
        },
        {
          "body": {
            "type": "tpl",
            "tpl": "北京"
          }
        }
      ]
    },
    {
      "tds": [
        {
          "body": {
            "type": "tpl",
            "tpl": "天津"
          }
        }
      ]
    }
  ]
}
```

| 属性名 | 类型     | 默认值 | 说明                 |
| ------ | -------- | ------ | -------------------- |
| span   | `number` |        | 这是个跨几列的设置项 |
| style  | `object` |        | 列样式               |

### 标题设置

可以通过 `caption` 来添加段标题文本，并通过 `captionSide` 来控制显示在底部还是顶部。

```schema: scope="body"
{
  "type": "table-view",
  "caption": "标题",
  "captionSide": "bottom",
  "trs": [
    {
      "tds": [
        {
          "rowspan": 2,
          "body": {
            "type": "tpl",
            "tpl": "华北"
          }
        },
        {
          "body": {
            "type": "tpl",
            "tpl": "北京"
          }
        },
        {
          "body": {
            "type": "tpl",
            "tpl": "${beijing}"
          }
        }
      ]
    },
    {
      "tds": [
        {
          "body": {
            "type": "tpl",
            "tpl": "天津"
          }
        },
        {
          "body": {
            "type": "tpl",
            "tpl": "${tianjing}"
          }
        }
      ]
    }
  ]
}
```

### 支持变量及表达式

> 2.1.0 及以上版本

table-view 的所有属性都支持变量，比如下面的例子通过表达式实现了针对数据进行不同展示

```schema
{
  "type": "page",
  "title": "标题",
  "data": {
    "score": 40
  },
  "body": {
    "type": "table-view",
    "trs": [
      {
        "tds": [
          {
            "background": "${score>50 ? '#fef1d2': '#d7f8ff'}",
            "body": {
              "type": "tpl",
              "tpl": "分数>50"
            }
          },
          {
            "background": "${score<100 ? '#fef1d2': '#d7f8ff'}",
            "body": {
              "type": "tpl",
              "tpl": "分数<100"
            }
          }
        ]
      }
    ]
  }
}
```

### tr 和 td 支持 visibleOn

> 6.5 及以后版本

可以在行和列上配置 visibleOn 或 hiddenOn 属性来实现根据数据动态渲染界面。

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 作为布局方法

table-view 除了可以用来展现表格类型的数据，还能用来实现复杂布局效果，只需要将 `border` 隐藏就行，除了拆分单元格还能通过嵌套的方式实现布局，比如：

```
/* Detailed source-code truncated for AI context efficiency. */
```

---

### Zh CN Components Table (`docs/zh-CN/components/table.md`)

---
title: Table 表格
description:
type: 0
group: ⚙ 组件
menuName: Table 表格
icon:
order: 67
---

表格展示，不支持配置初始化接口初始化数据域，所以需要搭配类似像`Service`这样的，具有配置接口初始化数据域功能的组件，或者手动进行数据域初始化，然后通过`source`属性，获取数据链中的数据，完成数据展示。

## 基本用法

```schema: scope="body"
{
    "type": "service",
    "api": "/api/mock2/sample?perPage=5",
    "body": [
        {
            "type": "table",
            "title": "表格1",
            "source": "$rows",
            "columns": [
                {
                    "name": "engine",
                    "label": "Engine"
                },

                {
                    "name": "version",
                    "label": "Version"
                }
            ]
        }
    ]
}
```

## 数据需求

数据是对象数组，比如前面的例子中 `rows` 的值类似：

```
[
    {
        "engine": "webkie",
        "version": 1
    }
]
```

## 空状态展示

```schema: scope="body"
{
    "type": "service",
    "api": "/api/mock2/sample?perPage=5",
    "body": [
        {
            "type": "table",
            "title": "表格1",
            "source": [],
            "columns": [
                {
                    "name": "engine",
                    "label": "Engine"
                },

                {
                    "name": "version",
                    "label": "Version"
                }
            ],
            "placeholder": "您还没有创建任何实例"
        }
    ]
}
```

## 列配置

`columns`内，除了简单的配置`label`和`name`展示数据以外，还支持一些额外的配置项，可以帮助更好的展示数据。

### 列类型

除了简单展示数据源所返回的数据以外，`list`的列支持除表单项以外所有组件类型，例如：

```
/* Detailed source-code truncated for AI context efficiency. */
```

### 列宽

可以给列配置 `width` 属性，控制列宽，共有两种方式：

#### 固定像素

可以配置数字，用于设置列宽像素，例如下面例子我们给`Rendering engine`列宽设置为`100px`。

> - 如果希望精准的控制列宽，请设置表格的 `tableLayout` 为 `fixed` 模式，同时为了让表格标题不换行，标题文字的长短会影响列的最小宽度
> - 注意：`resizable`开启后，固定宽度的列则无法拖动调整列宽

```schema: scope="body"
{
    "type": "crud",
    "api": "/api/mock2/sample?waitSeconds=1",
    "tableLayout": "fixed",
    "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "engine",
            "label": "Rendering engine",
            "width": 150
        },
        {
            "name": "browser",
            "label": "Browser"
        }
    ]
}
```

#### 百分比

也可以百分比来指定列宽，例如下面例子我们给`Rendering engine`列宽设置为`50%`。

```schema: scope="body"
{
    "type": "crud",
    "api": "/api/mock2/sample?waitSeconds=1",
    "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "engine",
            "label": "Rendering engine",
            "width": "50%"
        }
    ]
}
```

### 列对齐方式

> 1.4.0 及以上版本

通过 align 可以控制列文本对齐方式，比如

```schema: scope="body"
{
    "type": "service",
    "api": "/api/mock2/sample?perPage=5",
    "body": [
      {
        "type": "table",
        "title": "表格1",
        "source": "$rows",
        "columns": [
          {
            "name": "engine",
            "label": "Engine"
          },
          {
            "label": "Version",
            "type": "tpl",
            "tpl": "${version | number}",
            "align": "right"
          }
        ]
      }
    ]
}
```

### 列样式

> 1.4.0 及以上版本

除了前面的宽度和对齐方式，还有更灵活的控制方法是通过样式表

```schema: scope="body"
{
    "type": "service",
    "api": "/api/mock2/sample?perPage=5",
    "body": [
      {
        "type": "table",
        "title": "表格1",
        "source": "$rows",
        "columns": [
          {
            "name": "engine",
            "label": "Engine"
          },
          {
            "name": "version",
            "label": "Version",
            "className": "text-primary"
          }
        ]
      }
    ]
}
```

如果要单独设置标题的样式，可以使用 `labelClassName` 属性

```schema: scope="body"
{
    "type": "service",
    "api": "/api/mock2/sample?perPage=5",
    "body": [
      {
        "type": "table",
        "title": "表格1",
        "source": "$rows",
        "columns": [
          {
            "name": "engine",
            "label": "Engine"
          },
          {
            "name": "version",
            "label": "Version",
            "className": "text-primary",
            "labelClassName": "font-bold"
          }
        ]
      }
    ]
}
```

### 单元格样式

> 1.4.0 及以上版本

`classNameExpr` 可以根据数据动态添加 CSS 类，支持 [模板](../../docs/concepts/template) 语法。

例如下例，`"${ version > 5 ? 'text-danger' : '' }"` 表示当行数据的 `version` 数据大于 5 的时候添加 `text-danger` CSS 类名，使得文字颜色变红

```schema: scope="body"
{
    "type": "service",
    "api": "/api/mock2/sample?perPage=5",
    "body": [
        {
            "type": "table",
            "source": "$rows",

            "columns": [
                {
                    "name": "engine",
                    "label": "Engine"
                },
                {
                    "name": "version",
                    "label": "Version",
                    "classNameExpr": "${ version > 5 ? 'text-danger' : '' }",
                },
                {
                    "name": "grade",
                    "label": "Grade"
                }
            ]
        }
    ]
}
```

### 背景色阶

> 1.8.0 及以上版本

`backgroundScale` 可以用来根据数据控制自动分配色阶

```
/* Detailed source-code truncated for AI context efficiency. */
```

`min` 和 `max` 都支持变量，如果为设置会自动计算当前列的最大和最小值。

默认会从当前列的 `name` 属性来获取数据，也可以通过 `backgroundScale.source` 使用变量及公式来获取数据。

### 默认是否显示

默认 `columnsTogglable` 配置为 `auto`，当列超过 5 列后，就会在工具栏多渲染出来一个列展示与否的开关。你可以设置成 `true` 或者 `false` 来强制开或者关。在列配置中可以通过配置 `toggled` 为 `false` 默认不展示这列，比如下面这个例子中 ID 这一栏。

```schema: scope="body"
{
    "type": "service",
    "api": "/api/mock2/sample?perPage=5",
    "body": [
        {
            "type": "table",
            "source": "$rows",
            "className": "m-b-none",
            "columns": [
                {
                    "name": "engine",
                    "label": "Engine"
                },

                {
                    "name": "grade",
                    "label": "Grade"
                },

                {
                    "name": "version",
                    "label": "Version"
                },

                {
                    "name": "browser",
                    "label": "Browser"
                },

                {
                    "name": "id",
                    "label": "ID",
                    "toggled": false
                },

                {
                    "name": "platform",
                    "label": "Platform"
                }
            ]
        }
    ]
}
```

### 固定列

列太多可以让重要的几列固定，可以配置固定在左侧还是右侧，只需要给需要固定的列上配置 `fixed` 属性，配置 `left` 或者 `right`。

```
/* Detailed source-code truncated for AI context efficiency. */
```

### 可复制

可以在列上配置`"copyable": true`，会在该列的内容区里，渲染一个复制内容的图标，点击可复制该显示内容

```schema: scope="body"
{
    "type": "crud",
    "api": "/api/mock2/sample?waitSeconds=1",
    "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "engine",
            "label": "Rendering engine",
            "copyable": true
        }
    ]
}
```

你也可以配置对象形式，可以自定义显示内容

```schema: scope="body"
{
    "type": "crud",
    "api": "/api/mock2/sample?waitSeconds=1",
    "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "engine",
            "label": "Rendering engine",
            "copyable": {
                "content": "复制的内容是：${engine}"
            }
        }
    ]
}
```

### 弹出框（popOver）

可以给列上配置 `popOver` 属性，会在该列的内容区里，渲染一个图标，点击会显示弹出框，用于展示内容

```
/* Detailed source-code truncated for AI context efficiency. */
```

popOver 的其它配置请参考 [popover](./popover)

### 表头样式

可以配置`"isHead": true`，来让当前列以表头的样式展示。应用场景是：

1. 所有列`label`配置空字符串，不显示表头
2. 配置`combineNum`，合并单元格，实现左侧表头的形式
3. 列上配置`"isHead": true`，调整样式

```schema: scope="body"
{
  "type": "crud",
  "api": "/api/mock2/sample?waitSeconds=1",
  "affixHeader": false,
  "combineNum": 1,
  "columns": [
    {
      "name": "engine",
      "label": "",
      "isHead": true
    },
    {
      "name": "browser",
      "label": ""
    },
    {
      "name": "platform",
      "label": ""
    },
    {
      "name": "version",
      "label": ""
    },
    {
      "name": "grade",
      "label": ""
    }
  ]
}
```

还可以配置"offset"，实现弹出框位置调整自定义

```schema: scope="body"
{
    "type": "crud",
    "api": "/api/mock2/sample?waitSeconds=1",
    "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "engine",
            "label": "Rendering engine",
            "popOver": {
                "body": {
                    "type": "tpl",
                    "tpl": "偏了一点的popover"
                },
                "offset": {
                    "y": 100
                }
            }
        }
    ]
}
```

## 嵌套

当行数据中存在 children 属性时，可以自动嵌套显示下去。

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 显示序号

通过配置 `showIndex` 为 true，开启展示序号。

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 底部展示 (Footable)

列太多时，内容没办法全部显示完，可以让部分信息在底部显示，可以让用户展开查看详情。配置很简单，只需要开启 `footable` 属性，同时将想在底部展示的列加个 `breakpoint` 属性为 `*` 即可。

```schema: scope="body"
{
    "type": "service",
    "api": "/api/mock2/sample?perPage=5",
    "body": [
        {
            "type": "table",
            "source": "$rows",
            "className": "m-b-none",
            "columnsTogglable": false,
            "footable": true,
            "columns": [
                {
                    "name": "engine",
                    "label": "Engine"
                },

                {
                    "name": "grade",
                    "label": "Grade"
                },

                {
                    "name": "version",
                    "label": "Version",
                    "breakpoint": "*"
                },

                {
                    "name": "browser",
                    "label": "Browser",
                    "breakpoint": "*"
                },

                {
                    "name": "id",
                    "label": "ID",
                    "breakpoint": "*"
                },

                {
                    "name": "platform",
                    "label": "Platform",
                    "breakpoint": "*"
                }
            ]
        }
    ]
}
```

默认都不会展开，如果你想默认展开第一个就把 footable 配置成这样。

```json
{
  "footable": {
    "expand": "first"
  }
}
```

当配置成 `all` 时表示全部展开。

## 合并单元格

只需要配置 `combineNum` 属性即可，他表示从左到右多少列内启动自动合并单元格，只要多行的同一个属性值是一样的，就会自动合并。

如果你不想从第一列开始合并单元格，可以配置 `combineFromIndex`，如果配置为 1，则会跳过第一列的合并。如果配置为 2，则会跳过第一列和第二列的合并，从第三行开始向右合并 `combineNum` 列。

```
/* Detailed source-code truncated for AI context efficiency. */
```

> 1.3.0 版本开始 combineNum 支持使用变量，如下所示

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 超级表头

超级表头意思是，表头还可以再一次进行分组。额外添加个 `groupName` 属性即可。

```schema: scope="body"
{
    "type": "service",
    "api": "/api/mock2/sample?perPage=5",
    "body": [
        {
            "type": "table",
            "source": "$rows",
            "className": "m-b-none",
            "columns": [
                {
                    "name": "engine",
                    "label": "Engine",
                    "groupName": "分组1"
                },

                {
                    "name": "grade",
                    "label": "Grade",
                    "groupName": "分组1"
                },

                {
                    "name": "version",
                    "label": "Version",
                    "groupName": "分组2"
                },

                {
                    "name": "browser",
                    "label": "Browser",
                    "groupName": "分组2"
                },

                {
                    "name": "id",
                    "label": "ID",
                    "toggled": false,
                    "groupName": "分组2"
                },

                {
                    "name": "platform",
                    "label": "Platform",
                    "groupName": "分组2"
                }
            ]
        }
    ]
}
```

## 高亮行

可以通过配置`rowClassNameExpr`来为行添加 CSS 类，支持 [模板](../../docs/concepts/template) 语法。

例如下例，`"${id % 2 ? "bg-success" : ""}"` 表示当行数据的 `id` 变量为 不能被 `2` 整除时，给当前行添加`bg-success` CSS 类名，即绿色背景色

```schema: scope="body"
{
    "type": "service",
    "api": "/api/mock2/sample?perPage=10",
    "body": [
        {
            "type": "table",
            "source": "$rows",
            "rowClassNameExpr": "${id % 2 ? 'bg-success' : 'bg-blue-50'}",
            "columns": [
                {
                    "name": "engine",
                    "label": "Engine"
                },

                {
                    "name": "grade",
                    "label": "Grade"
                },

                {
                    "name": "version",
                    "label": "Version"
                },

                {
                    "name": "browser",
                    "label": "Browser"
                },

                {
                    "name": "id",
                    "label": "ID"
                },

                {
                    "name": "platform",
                    "label": "Platform"
                }
            ]
        }
    ]
}
```

## 总结行

可以通过配置 `prefixRow` 或 `affixRow` 来为表格顶部或底部添加总结行，

```schema: scope="body"
{
    "type": "service",
    "api": "/api/mock2/sample?perPage=10",
    "body": [
        {
            "type": "table",
            "source": "$rows",
            "columns": [
                {
                    "name": "browser",
                    "label": "Browser"
                },

                {
                    "name": "version",
                    "label": "Version"
                }
            ],
            "affixRow":[
                {
                    "type": "text",
                    "text": "总计"
                },
                {
                    "type": "tpl",
                    "tpl": "${rows|pick:version|sum}"
                }
            ]
        }
    ]
}
```

> 1.8.1 及以上版本

新增 `affixRowClassNameExpr`、`affixRowClassName`、`prefixRowClassNameExpr`、`prefixRowClassName` 来控制总结行样式，比如下面的例子

```schema: scope="body"
{
    "type": "service",
    "api": "/api/mock2/sample?perPage=10",
    "body": [
        {
            "type": "table",
            "source": "$rows",
            "columns": [
                {
                    "name": "browser",
                    "label": "Browser"
                },

                {
                    "name": "version",
                    "label": "Version"
                }
            ],
            "affixRowClassNameExpr": "${SUM(ARRAYMAP(rows, item => item.version)) > 30 ? 'text-success' : ''}",
            "affixRow":[
                {
                    "type": "text",
                    "text": "总计"
                },
                {
                    "type": "tpl",
                    "tpl": "${rows|pick:version|sum}"
                }
            ]
        }
    ]
}
```

### 配置合并单元格

可以配置 `colSpan` 来设置一列所合并的列数，例如

```schema: scope="body"
{
    "type": "service",
    "api": "/api/mock2/sample?perPage=10",
    "body": [
        {
            "type": "table",
            "source": "$rows",
            "columns": [
                {
                    "name": "id",
                    "label": "ID"
                },

                {
                    "name": "browser",
                    "label": "Browser"
                },

                {
                    "name": "version",
                    "label": "Version"
                }
            ],
            "affixRow":[
                {
                    "type": "text",
                    "text": "总计",
                    "colSpan": 2
                },
                {
                    "type": "tpl",
                    "tpl": "${rows|pick:version|sum}"
                }
            ]
        }
    ]
}
```

上例中我们给 `总计` 列配置了 `"colSpan": 2`，它会合并两个单元格

### 配置多行

可以配置二维数组来配置多行总结行

```schema: scope="body"
{
    "type": "service",
    "api": "/api/mock2/sample?perPage=10",
    "body": [
        {
            "type": "table",
            "source": "$rows",
            "columns": [
                {
                    "name": "browser",
                    "label": "Browser"
                },

                {
                    "name": "version",
                    "label": "Version"
                }
            ],
            "affixRow":[
                [
                    {
                        "type": "text",
                        "text": "总计1"
                    },
                    {
                        "type": "tpl",
                        "tpl": "${rows|pick:version|sum}"
                    }
                ],
                [
                    {
                        "type": "text",
                        "text": "总计2"
                    },
                    {
                        "type": "tpl",
                        "tpl": "${rows|pick:version|sum}"
                    }
                ]
            ]
        }
    ]
}
```

## 行操作按钮

通过 itemActions 可以设置鼠标移动到行上出现操作按钮

```schema: scope="body"
{
  "type": "service",
  "api": "/api/mock2/sample?perPage=10",
  "body": [{
    "type": "table",
    "source": "$rows",
    "itemActions": [{
      "label": "编辑",
      "type": "button",
      "actionType": "dialog",
      "dialog": {
        "title": "编辑",
        "body": "这是个简单的编辑弹框"
      }
    }, {
      "label": "删除",
      "type": "button",
      "actionType": "ajax",
      "confirmText": "确认要删除？",
      "api": "/api/mock2/form/saveForm"
    }],
    "columns": [{
        "name": "browser",
        "label": "Browser"
      },

      {
        "name": "version",
        "label": "Version"
      }
    ]
  }]
}
```

## 单行点击操作

> 1.4.0 及以上版本

处理前面的 itemActions，还可以配置 itemAction 来实现点击某一行后进行操作，支持 [action](./action) 里的所有配置，比如弹框、刷新其它组件等。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/mock2/sample?perPage=10",
  "body": [{
    "type": "table",
    "source": "$rows",
    "itemAction": {
      "type": "button",
      "actionType": "dialog",
      "dialog": {
        "title": "详情",
        "body": "当前行的数据 browser: ${browser}, version: ${version}"
      }
    },
    "columns": [{
        "name": "browser",
        "label": "Browser"
      },
      {
        "name": "version",
        "label": "Version"
      }
    ]
  }]
}
```

注意这个属性和 `checkOnItemClick` 冲突，因为都是定义行的点击行为，开启 `itemAction` 后 `checkOnItemClick` 将会失效。

## 行角标

> 1.5.0 及以上版本

通过属性`itemBadge`，可以为表格行配置[角标](./badge)，可以使用[数据映射](../../../docs/concepts/data-mapping)为每一行添加特定的 Badge 属性。[`visibleOn`](../../../docs/concepts/expression)属性控制显示的条件，表达式中`this`可以取到行所在上下文的数据，比如行数据中有`badgeText`字段才显示角标，可以设置`"visibleOn": "this.badgeText"`

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 表格内容高度自适应

> 1.5.0 及以上版本

通过 `autoFillHeight` 可以让表格内容区自适应高度，具体效果请看这个[示例](../../examples/crud/auto-fill)。

它的展现效果是整个内容区域高度自适应，表格内容较多时在内容区域内出滚动条，这样顶部筛选和底部翻页的位置都是固定的。

开启这个配置后会自动关闭 `affixHeader` 功能避免冲突。

## 属性表

| 属性名           | 类型                                                     | 默认值                    | 说明                                                                                                                                                                                                   | 版本                              |
| ---------------- | -------------------------------------------------------- | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------- |
| type             | `string`                                                 |                           | `"type"` 指定为 table 渲染器                                                                                                                                                                           |                                   |
| title            | `string`                                                 |                           | 标题                                                                                                                                                                                                   |                                   |
| source           | `string`                                                 | `${items}`                | 数据源, 绑定当前环境变量                                                                                                                                                                               |                                   |
| deferApi         | [API](../../docs/types/api)                              |                           | 当行数据中有 defer 属性时，用此接口进一步加载内容                                                                                                                                                      |
| affixHeader      | `boolean`                                                | `true`                    | 是否固定表头                                                                                                                                                                                           |                                   |
| affixFooter      | `boolean`                                                | `false`                   | 是否固定表格底部工具栏                                                                                                                                                                                 |                                   |
| columnsTogglable | `auto` 或者 `boolean`                                    | `auto`                    | 展示列显示开关, 自动即：列数量大于或等于 5 个时自动开启                                                                                                                                                |                                   |
| placeholder      | `string` 或者 `SchemaTpl`                                | `暂无数据`                | 当没数据的时候的文字提示                                                                                                                                                                               |                                   |
| className        | `string`                                                 | `panel-default`           | 外层 CSS 类名                                                                                                                                                                                          |                                   |
| showIndex        | `boolean`                                                |                           | 是否展示序号                                                                                                                                                                                           | 6.11.0                            |
| tableClassName   | `string`                                                 | `table-db table-striped`  | 表格 CSS 类名                                                                                                                                                                                          |                                   |
| headerClassName  | `string`                                                 | `Action.md-table-header`  | 顶部外层 CSS 类名                                                                                                                                                                                      |                                   |
| footerClassName  | `string`                                                 | `Action.md-table-footer`  | 底部外层 CSS 类名                                                                                                                                                                                      |                                   |
| toolbarClassName | `string`                                                 | `Action.md-table-toolbar` | 工具栏 CSS 类名                                                                                                                                                                                        |                                   |
| columns          | `Array<Column>`                                          |                           | 用来设置列信息                                                                                                                                                                                         |                                   |
| combineNum       | `number`                                                 |                           | 自动合并单元格                                                                                                                                                                                         |                                   |
| itemActions      | Array<[Action](./action-button)>                         |                           | 悬浮行操作按钮组                                                                                                                                                                                       |                                   |
| itemCheckableOn  | [表达式](../../docs/concepts/expression)                 |                           | 配置当前行是否可勾选的条件，要用 [表达式](../../docs/concepts/expression)                                                                                                                              |                                   |
| itemDraggableOn  | [表达式](../../docs/concepts/expression)                 |                           | 配置当前行是否可拖拽的条件，要用 [表达式](../../docs/concepts/expression)                                                                                                                              |                                   |
| checkOnItemClick | `boolean`                                                | `false`                   | 点击数据行是否可以勾选当前行                                                                                                                                                                           |                                   |
| rowClassName     | `string`                                                 |                           | 给行添加 CSS 类名                                                                                                                                                                                      |                                   |
| rowClassNameExpr | [模板](../../docs/concepts/template)                     |                           | 通过模板给行添加 CSS 类名                                                                                                                                                                              |                                   |
| prefixRow        | `Array`                                                  |                           | 顶部总结行                                                                                                                                                                                             |                                   |
| affixRow         | `Array`                                                  |                           | 底部总结行                                                                                                                                                                                             |                                   |
| itemBadge        | [`BadgeSchema`](./badge)                                 |                           | 行角标配置                                                                                                                                                                                             |                                   |
| autoFillHeight   | `boolean` 丨 `{height: number}` 丨 `{maxHeight: number}` |                           | 内容区域自适应高度，可选择自适应、固定高度和最大高度                                                                                                                                                   | `maxHeight` 需要 `2.8.0` 以上版本 |
| resizable        | `boolean`                                                | `true`                    | 列宽度是否支持调整                                                                                                                                                                                     |                                   |
| selectable       | `boolean`                                                | `false`                   | 支持勾选                                                                                                                                                                                               |                                   |
| multiple         | `boolean`                                                | `false`                   | 勾选 icon 是否为多选样式`checkbox`， 默认为`radio`                                                                                                                                                     |                                   |
| lazyRenderAfter  | `number`                                                 | `100`                     | 用来控制从第几行开始懒渲染行，用来渲染大表格时有用                                                                                                                                                     |                                   |
| tableLayout      | `auto` \| `fixed`                                        | `auto`                    | 当配置为 fixed 时，内容将不会撑开表格，自动换行                                                                                                                                                        |                                   |
| reUseRow         | `false` \| `match`                                       |                           | 默认，当 API 返回数据与当前一致时，不会触发表格行重渲染（省性能但可能导致数据渲染不同步）；为 false，则总会触发重渲染；为 match，尽量复用返回数据中 id 一致的对象，性能可认为是默认和 false 两者的折中 |                                   |
| persistKey       | `string`                                                 |                           | 用于配置列排序、列显示的本地缓存所使用的 key                                                                                                                                                           |                                   |

### 列配置属性表

| 属性名       | 类型                                          | 默认值    | 说明                                                                                                           | 版本     |
| ------------ | --------------------------------------------- | --------- | -------------------------------------------------------------------------------------------------------------- | -------- |
| label        | [模板](../../docs/concepts/template)          |           | 表头文本内容                                                                                                   |          |
| name         | `string`                                      |           | 通过名称关联数据                                                                                               |          |
| width        | `number` \| `string`                          |           | 列宽                                                                                                           |          |
| remark       |                                               |           | 提示信息                                                                                                       |          |
| fixed        | `left` \| `right` \| `none`                   |           | 是否固定当前列                                                                                                 |          |
| popOver      |                                               |           | 弹出框                                                                                                         |          |
| copyable     | `boolean` 或 `{icon: string, content:string}` |           | 是否可复制                                                                                                     |          |
| style        | `object`                                      |           | 单元格自定义样式                                                                                               |          |
| innerStyle   | `object`                                      |           | 单元格内部组件自定义样式                                                                                       | `2.8.1`  |
| align        | `left` \| `right` \| `center` \| `justify`    |           | 单元格对齐方式                                                                                                 | ` 1.4.0` |
| headerAlign  | `left` \| `right` \| `center` \| `justify`    |           | 表头单元格对齐方式                                                                                             | `6.7.0`  |
| vAlign       | `top` \| `middle` \| `bottom`                 |           | 单元格垂直对齐方式                                                                                             | `6.7.0`  |
| textOverflow | `string`                                      | `default` | 文本溢出后展示形式，默认换行处理。可选值 `ellipsis` 溢出隐藏展示， `noWrap` 不换行展示(仅在列为静态文本时生效) | `6.10.0` |

## 事件表

当前组件会对外派发以下事件，可以通过`onEvent`来监听这些事件，并通过`actions`来配置执行的动作，在`actions`中可以通过`${事件参数名}`或`${event.data.[事件参数名]}`来获取事件产生的数据，详细查看[事件动作](../../docs/concepts/event-action)。

| 事件名称       | 事件参数                                                                                                             | 说明                 |
| -------------- | -------------------------------------------------------------------------------------------------------------------- | -------------------- |
| selectedChange | `selectedItems: item[]` 已选择行<br/>`selectedIndexes: string[]` 已选择行索引<br/>`unSelectedItems: item[]` 未选择行 | 手动选择表格项时触发 |
| columnSort     | `orderBy: string` 列排序列名<br/>`orderDir: string` 列排序值                                                         | 点击列排序时触发     |
| columnFilter   | `filterName: string` 列筛选列名<br/>`filterValue: string` 列筛选值                                                   | 点击列筛选时触发     |
| columnSearch   | `searchName: string` 列搜索列名<br/>`searchValue: string` 列搜索数据                                                 | 点击列搜索时触发     |
| orderChange    | `movedItems: item[]` 已排序数据                                                                                      | 手动拖拽行排序时触发 |
| columnToggled  | `columns: item[]` 当前显示的列配置数据                                                                               | 点击自定义列时触发   |
| rowClick       | `item: object` 行点击数据<br/>`index: number` 行索引 <br />`indexPath: string` 行索引路径                            | 单击整行时触发       |
| rowDbClick     | `item: object` 行点击数据<br/>`index: number` 行索引 <br />`indexPath: string` 行索引路径                            | 双击整行时触发       |
| rowMouseEnter  | `item: object` 行移入数据<br/>`index: number` 行索引 <br />`indexPath: string` 行索引路径                            | 移入整行时触发       |
| rowMouseLeave  | `item: object` 行移出数据<br/>`index: number` 行索引 <br />`indexPath: string` 行索引路径                            | 移出整行时触发       |

### selectedChange

在开启批量操作后才会用到，可以尝试勾选列表的行记录。

```schema: scope="body"
{
    "type": "service",
    "api": "/api/mock2/sample?perPage=10",
    "body": [
        {
            "type": "table",
            "source": "$rows",
            "selectable": true,
            "onEvent": {
                "selectedChange": {
                    "actions": [
                        {
                            "actionType": "toast",
                            "args": {
                                "msg": "已选择${event.data.selectedItems.length}条记录"
                            }
                        }
                    ]
                }
            },
            "columns": [
                {
                    "name": "id",
                    "label": "ID"
                },
                {
                    "name": "engine",
                    "label": "Rendering engine"
                },
                {
                    "name": "browser",
                    "label": "Browser"
                },
                {
                    "name": "platform",
                    "label": "Platform(s)"
                },
                {
                    "name": "version",
                    "label": "Engine version"
                },
                {
                    "name": "grade",
                    "label": "CSS grade"
                }
            ]
        }
    ]
}
```

### columnSort

列排序，可以尝试点击`Browser`列右侧的排序图标。

```
/* Detailed source-code truncated for AI context efficiency. */
```

### columnFilter

列过滤，可以尝试点击`Rendering engine`列右侧的筛选图标。

```
/* Detailed source-code truncated for AI context efficiency. */
```

### columnSearch

列检索，，可以尝试点击`ID`列右侧的检索图标。

```
/* Detailed source-code truncated for AI context efficiency. */
```

### columnToggled

点击自定义列，可以尝试修改`自定义列`的配置。

```
/* Detailed source-code truncated for AI context efficiency. */
```

### orderChange

在开启拖拽排序行记录后才会用到，排序确认后触发。

```
/* Detailed source-code truncated for AI context efficiency. */
```

### rowClick

点击行记录。

```
/* Detailed source-code truncated for AI context efficiency. */
```

### rowDbClick

双击整行时触发。

```
/* Detailed source-code truncated for AI context efficiency. */
```

### rowMouseEnter

鼠标移入行记录。

```
/* Detailed source-code truncated for AI context efficiency. */
```

### rowMouseLeave

鼠标移出行记录。

```
/* Detailed source-code truncated for AI context efficiency. */
```

### 列的事件表

表格的默认列定义的事件如下，即 click、mouseenter、mouseleave。如果列定义是其他组件，则事件表就是这个组件对应的事件表，例如列定义是 Switch 组件，则可以监听 [Switch 的 change 事件](./form/switch#%E4%BA%8B%E4%BB%B6%E8%A1%A8)。

| 事件名称   | 事件参数                            | 说明                                           |
| ---------- | ----------------------------------- | ---------------------------------------------- |
| click      | `[columnName]: string` 对应列名的值 | 监听表格列点击事件，表格数据点击时触发         |
| mouseenter | `[columnName]: string` 对应列名的值 | 监听表格列鼠标移入事件，表格数据鼠标移入时触发 |
| mouseleave | `[columnName]: string` 对应列名的值 | 监听表格列鼠标移出事件，表格数据鼠标移出时触发 |

可以尝试点击某行的`Rendering engine`列数据、鼠标移入某行的`Browser`列数据。

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 动作表

当前组件对外暴露以下特性动作，其他组件可以通过指定`actionType: 动作名称`、`componentId: 该组件id`来触发这些动作，动作配置可以通过`args: {动作配置项名称: xxx}`来配置具体的参数，详细请查看[事件动作](../../docs/concepts/event-action#触发其他组件的动作)。

| 动作名称        | 动作配置                                                                                                                                                                                                                                                                                                                                                                                                | 说明                       |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- |
| select          | `args.selected`: string 条件表达式，**不推荐，建议用 `args.index` 或者 `args.condition`** 表达式中可以访问变量`record:行数据`和`rowIndex:行索引`，例如: data.rowIndex === 1 <br /> `args.index` 可选，指定行数，支持表达式，支持树形路径（当为树形表格的时候使用）表达式上下文为对应行数据，跟 `args.select` 的上下文不同。 <br /> `args.condition` 可选，通过表达式指定更新哪些行，支持条件组合 index` | 设置表格的选中项           |
| selectAll       | -                                                                                                                                                                                                                                                                                                                                                                                                       | 设置表格全部项选中         |
| clearAll        | -                                                                                                                                                                                                                                                                                                                                                                                                       | 清空表格所有选中项         |
| initDrag        | -                                                                                                                                                                                                                                                                                                                                                                                                       | 开启表格拖拽排序功能       |
| cancelDrag      | -                                                                                                                                                                                                                                                                                                                                                                                                       | 放弃表格拖拽排序功能       |
| setValue        | `args.value`: object <br />`args.index` 可选，指定行数，支持表达式，支持树形路径（当为树形表格的时候使用） <br /> `args.condition` 可选，通过表达式指定更新哪些行，支持条件组合                                                                                                                                                                                                                         | 更新列表记录               |
| submitQuickEdit |                                                                                                                                                                                                                                                                                                                                                                                                         | 快速编辑数据提交           |
| toggleExpanded  | `args.index` 可选，指定行数，支持表达式，支持树形路径（当为树形表格的时候使用） <br /> `args.condition` 可选，通过表达式指定更新哪些行，支持条件组合                                                                                                                                                                                                                                                    | 切换某行数据是展开还是收起 |
| setExpanded     | `args.index` 可选，指定行数，支持表达式，支持树形路径（当为树形表格的时候使用） <br /> `args.condition` 可选，通过表达式指定更新哪些行，支持条件组合 <br /> `args.value` 展开还是收起                                                                                                                                                                                                                   | 设置某行数据展开还是收起   |

value 结构说明：

| 属性名        | 类型     | 默认值 | 说明     |
| ------------- | -------- | ------ | -------- |
| items 或 rows | `item[]` |        | 列表记录 |

### select

> 6.3.0 或更高版本

- `args.index` 可选，指定行数，支持表达式，支持树形路径（当为树形表格的时候使用）
- `args.condition` 可选，通过表达式指定更新哪些行，支持条件组合
- `args.selected` 不推荐使用，请使用以上两者替代

> 注意 6.3.0 版本开始用法变动，通过 `args.index` 和 `args.condition` 来代替 `args.selected`, 同时表达式上下文为对应行数据，跟 `args.select` 的上下文不同。

```schema: scope="body"
[
    {
    "type": "button-toolbar",
    "className": "m-b",
    "buttons": [
    {
        "name": "trigger1",
        "id": "trigger1",
        "type": "action",
        "label": "选中前两个",
        "onEvent": {
        "click": {
            "actions": [
            {
                "actionType": "select",
                "componentId": "table-select",
                "args": {
                    "index": "0,1"
                }
            }
            ]
        }
        }
    }
    ]
},
{
    "type": "service",
    "api": "/api/mock2/sample?perPage=10",
    "body": [
    {
        "id": "table-select",
        "type": "table",
        "source": "$rows",
        "selectable": true,
        "multiple": true,
        "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "browser",
            "label": "Browser"
        },
        {
            "name": "version",
            "label": "Version"
        }
        ]
    }
    ]
}
]
```

### selectAll

```schema: scope="body"
[
    {
    "type": "button-toolbar",
    "className": "m-b",
    "buttons": [
    {
        "name": "trigger2",
        "id": "trigger2",
        "type": "action",
        "label": "设置表格全部项选中",
        "onEvent": {
        "click": {
            "actions": [
            {
                "actionType": "selectAll",
                "componentId": "table-select",
                "description": "点击设置指定表格全部内容选中"
            }
            ]
        }
        }
    }
    ]
},
{
    "type": "service",
    "api": "/api/mock2/sample?perPage=10",
    "body": [
    {
        "id": "table-select",
        "type": "table",
        "source": "$rows",
        "selectable": true,
        "multiple": true,
        "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "browser",
            "label": "Browser"
        },
        {
            "name": "version",
            "label": "Version"
        }
        ]
    }
    ]
}
]
```

### clearAll

```schema: scope="body"
[
    {
    "type": "button-toolbar",
    "className": "m-b",
    "buttons": [
    {
        "name": "trigger3",
        "id": "trigger3",
        "type": "action",
        "label": "清空表格全部选中项",
        "onEvent": {
        "click": {
            "actions": [
            {
                "actionType": "clearAll",
                "componentId": "table-select",
                "description": "点击设置指定表格全部选中项清空"
            }
            ]
        }
        }
    }
    ]
},
{
    "type": "service",
    "api": "/api/mock2/sample?perPage=10",
    "body": [
    {
        "id": "table-select",
        "type": "table",
        "source": "$rows",
        "selectable": true,
        "multiple": true,
        "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "browser",
            "label": "Browser"
        },
        {
            "name": "version",
            "label": "Version"
        }
        ]
    }
    ]
}
]
```

### initDrag & cancelDrag

```schema: scope="body"
[
    {
    "type": "button-toolbar",
    "className": "m-b",
    "buttons": [
    {
        "name": "trigger4",
        "id": "trigger4",
        "type": "action",
        "label": "开启表格行排序",
        "onEvent": {
        "click": {
            "actions": [
            {
                "actionType": "initDrag",
                "componentId": "table-select",
                "description": "点击开启表格行排序功能"
            }
            ]
        }
        }
    },
    {
        "name": "trigger5",
        "id": "trigger5",
        "type": "action",
        "label": "取消表格行排序",
        "onEvent": {
        "click": {
            "actions": [
            {
                "actionType": "cancelDrag",
                "componentId": "table-select",
                "description": "点击取消表格行排序功能"
            }
            ]
        }
        }
    }
    ]
},
{
    "type": "service",
    "api": "/api/mock2/sample?perPage=10",
    "body": [
    {
        "id": "table-select",
        "type": "table",
        "source": "$rows",
        "columns": [
        {
            "name": "id",
            "label": "ID"
        },
        {
            "name": "browser",
            "label": "Browser"
        },
        {
            "name": "version",
            "label": "Version"
        }
        ]
    }
    ]
}
]
```

### setValue

#### 更新列表记录

```
/* Detailed source-code truncated for AI context efficiency. */
```

#### 更新指定行记录

可以通过指定`index`或者`condition`来分别更新指定索引的行记录和指定满足条件（条件表达式或者 ConditionBuilder）的行记录，另外`replace`同样生效，即可以完全替换指定行记录，也可以对指定行记录做合并。

```
/* Detailed source-code truncated for AI context efficiency. */
```

---

### Zh CN Components Table2 (`docs/zh-CN/components/table2.md`)

---
title: Table2 表格
description:
type: 0
group: ⚙ 组件
menuName: Table 表格
icon:
order: 67
---

表格展示，不支持配置初始化接口初始化数据域，所以需要搭配类似像`Service`这样的，具有配置接口初始化数据域功能的组件，或者手动进行数据域初始化，然后通过`source`属性，获取数据链中的数据，完成数据展示。

## 基本用法

可配置表头（`title`）、表尾(`footer`)，同时支持文本或者 schema 类型。

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 可选择

可以通过配置`rowSelection`来支持单选或者多选，也可以配置`selectable`、`multiple`结合来实现，其中`selectable`、`multiple`的优先级更高。

### 多选

可以简单将`rowSelection`设置为`true`开启多选，也可以给`rowSelection`配置更多属性，不指定`type`则默认为多选。也可以设置`selectable`为`true`，同时`multiple`设置为`true`，同样可以开启多选。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/sample?perPage=5",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "rowSelection": {
        "type": "checkbox",
        "keyField": "id"
      },
      "columns": [
        {
          "title": "Engine",
          "name": "engine"
        },
        {
          "title": "Version",
          "name": "version"
        },
        {
          "title": "Browser",
          "name": "browser"
        },
        {
          "title": "Operation",
          "name": "operation",
          "type": "button",
          "label": "删除",
          "size": "sm"
        }
      ]
    }
  ]
}
```

### 点击整行选择

目前仅能通过`rowSelection.rowClick`属性来开启。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/sample?perPage=5",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "rowSelection": {
        "type": "checkbox",
        "keyField": "id",
        "rowClick": true
      },
      "columns": [
        {
          "title": "Engine",
          "name": "engine"
        },
        {
          "title": "Version",
          "name": "version"
        },
        {
          "title": "Browser",
          "name": "browser"
        },
        {
          "title": "Operation",
          "name": "operation",
          "type": "button",
          "label": "删除",
          "size": "sm"
        }
      ]
    }
  ]
}
```

### 已选择

通过`rowSelection.selectedRowKeys`属性来设置表格内已选中的项，可以使用`primaryField`、`rowSelection.keyField`或者`keyField`指定数据源中用来做值匹配的字段，优先级依次递减。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/sample?perPage=5",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "rowSelection": {
        "type": "checkbox",
        "keyField": "id",
        "selectedRowKeys": [1, 2]
      },
      "columns": [
        {
          "title": "ID",
          "name": "id"
        },
        {
          "title": "Engine",
          "name": "engine"
        },
        {
          "title": "Version",
          "name": "version"
        },
        {
          "title": "Browser",
          "name": "browser"
        },
        {
          "title": "Operation",
          "name": "operation",
          "type": "button",
          "label": "删除",
          "size": "sm"
        }
      ]
    }
  ]
}
```

### 已选择 - 表达式

还可以使用表达式的方式来匹配已选中的项，`rowSelection.selectedRowKeysExpr`可以配置表达式。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/sample?perPage=5",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "rowSelection": {
        "type": "checkbox",
        "keyField": "id",
        "selectedRowKeysExpr": "data.record.id === 1"
      },
      "columns": [
        {
          "title": "ID",
          "name": "id"
        },
        {
          "title": "Engine",
          "name": "engine"
        },
        {
          "title": "Version",
          "name": "version"
        },
        {
          "title": "Browser",
          "name": "browser"
        },
        {
          "title": "Operation",
          "name": "operation",
          "type": "button",
          "label": "删除",
          "size": "sm"
        }
      ]
    }
  ]
}
```

### 单选

设置`rowSelection.type`为`radio`或者设置`selectable`为`true`、`multiple`为`false`来实现单选，同时可通过`rowSelection.disableOn`来控制哪一行不可选，不可选情况下默认会有禁用样式，但如果行内有除文字外的其他组件，禁用样式需要自行控制。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/sample?perPage=5",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "rowSelection": {
        "type": "radio",
        "keyField": "id",
        "disableOn": "this.record.id === 1"
      },
      "columns": [
        {
          "title": "Engine",
          "name": "engine"
        },
        {
          "title": "Version",
          "name": "version"
        },
        {
          "title": "Browser",
          "name": "browser"
        }
      ]
    }
  ]
}
```

### 自定义选择菜单

内置全选`all`、反选`invert`、清空`none`、选中奇数行`odd`、选中偶数行`even`，可以通过`rowSelection.selections`自行配置，超出内置功能范围的不支持，配置了也无法使用。被禁用的行不参与计算奇偶数。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/sample?perPage=5",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "rowSelection": {
        "type": "checkbox",
        "keyField": "id",
        "selections": [
          {
            "key": "all",
            "text": "全选所有"
          },
          {
            "key": "invert",
            "text": "反选当页"
          },
          {
            "key": "none",
            "text": "清空所有"
          },
          {
            "key": "odd",
            "text": "选择奇数行"
          },
          {
            "key": "even",
            "text": "选择偶数行"
          }
        ]
      },
      "columns": [
        {
          "title": "Engine",
          "name": "engine"
        },
        {
          "title": "Version",
          "name": "version"
        },
        {
          "title": "Browser",
          "name": "browser"
        },
        {
          "title": "Operation",
          "name": "operation",
          "type": "button",
          "label": "删除",
          "size": "sm"
        }
      ]
    }
  ]
}
```

### 最大选择个数

可通过设置`maxKeepItemSelectionLength`控制表格可选中的最大个数。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/sample?perPage=5",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "maxKeepItemSelectionLength": 2,
      "rowSelection": {
        "type": "checkbox",
        "keyField": "id"
      },
      "columns": [
        {
          "title": "Engine",
          "name": "engine"
        },
        {
          "title": "Version",
          "name": "version"
        },
        {
          "title": "Browser",
          "name": "browser"
        },
        {
          "title": "Operation",
          "name": "operation",
          "type": "button",
          "label": "删除",
          "size": "sm"
        }
      ]
    }
  ]
}
```

## 筛选和排序

通过设置`column.sorter`开启列排序，只能通过`crud2`来看实际效果。通过`column.filters`开启列筛选，支持单选、多选两种模式，同样依赖`crud2`查看实际效果。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/sample?perPage=5",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "columns": [
        {
          "title": "Engine",
          "name": "engine",
          "sorter": true,
          "filterMultiple": true,
          "filters": [
            {
              "text": "Joe",
              "value": "Joe"
            },
            {
              "text": "Jim",
              "value": "Jim"
            }
          ]
        },
        {
          "title": "Version",
          "name": "version",
          "sorter": true,
          "width": 100
        },
        {
          "title": "Browser",
          "name": "browser",
          "filters": [
            {
              "text": "Joe",
              "value": "Joe"
            },
            {
              "text": "Jim",
              "value": "Jim"
            }
          ]
        }
      ]
    }
  ]
}
```

## 带边框

可通过`bordered`属性控制表格是否有边框。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/sample?perPage=5",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "bordered": true,
      "title": "标题",
      "footer": "Footer",
      "columns": [
        {
          "title": "Engine",
          "name": "engine"
        },
        {
          "title": "Version",
          "name": "version"
        },
        {
          "title": "Browser",
          "name": "browser"
        },
        {
          "title": "Operation",
          "name": "operation",
          "type": "button",
          "label": "删除",
          "size": "sm"
        }
      ]
    }
  ]
}
```

## 可展开

支持点击按钮展开/关闭当前行的自定义内容，展开按钮可放在表格的最左侧、最右侧或通过事件动作来触发展开。

### 默认展开

可简单设置`expandable`为`true`开启行展开功能，也可以在`expandable`属性上配置更多功能，`expandable.expandableOn`控制哪些行可以展开，`expandable.expandedRowKeys`控制哪些行默认展开，默认展开按钮放在表格最左侧。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/sample?perPage=5",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "columns": [
        {
          "title": "Engine",
          "name": "engine"
        },
        {
          "title": "Version",
          "name": "version"
        },
        {
          "title": "Browser",
          "name": "browser"
        },
        {
          "title": "Operation",
          "name": "operation",
          "type": "button",
          "label": "删除",
          "size": "sm"
        }
      ],
      "expandable": {
        "expandableOn": "this.record && (this.record.id === 1 || this.record.id === 3)",
        "keyField": "id",
        "expandedRowClassNameExpr": "${ rowIndex === 2 ? 'bg-success' : '' }",
        "expandedRowKeys": ["3"],
        "type": "container",
        "body": [
          {
            "type": "tpl",
            "html": "<div class=\"test\">测试测试</div>"
          }
        ]
      }
    }
  ]
}
```

### 默认展开 - 表达式

也可以通过设置`expandable.expandedRowKeysExpr`使用表达式来控制默认展开项。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/sample?perPage=5",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "columns": [
        {
          "title": "Engine",
          "name": "engine"
        },
        {
          "title": "Version",
          "name": "version"
        },
        {
          "title": "Browser",
          "name": "browser"
        },
        {
          "title": "Operation",
          "name": "operation",
          "type": "button",
          "label": "删除",
          "size": "sm"
        }
      ],
      "expandable": {
        "expandableOn": "this.record && (this.record.id === 1 || this.record.id === 3)",
        "keyField": "id",
        "expandedRowClassNameExpr": "${ rowIndex % 2 ? 'bg-success' : '' }",
        "expandedRowKeysExpr": "data.record.id == '3'",
        "type": "container",
        "body": [
          {
            "type": "tpl",
            "html": "<div class=\"test\">测试测试</div>"
          }
        ]
      }
    }
  ]
}
```

### 右侧展开按钮

通过设置`expandable.position`属性为`right`控制，支持不设置（展示在左侧）、`left`、`right`、`none`（无展开按钮）四种情况。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/sample?perPage=5",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "columns": [
        {
          "title": "Engine",
          "name": "engine"
        },
        {
          "title": "Version",
          "name": "version"
        },
        {
          "title": "Browser",
          "name": "browser"
        },
        {
          "title": "Operation",
          "name": "operation",
          "type": "button",
          "label": "删除",
          "size": "sm"
        }
      ],
      "expandable": {
        "expandableOn": "this.record && (this.record.id === 1 || this.record.id === 3)",
        "keyField": "id",
        "expandedRowClassNameExpr": "${ rowIndex % 2 ? 'bg-success' : '' }",
        "expandedRowKeys": ["3"],
        "type": "container",
        "position": "right",
        "body": [
          {
            "type": "tpl",
            "html": "<div class=\"test\">测试测试</div>"
          }
        ]
      },
      "footSummary": [
        {
          "type": "text",
          "text": "总计"
        },
        {
          "type": "tpl",
          "tpl": "测试测试",
          "colSpan": 2
        },
        {
          "type": "tpl",
          "tpl": "最后一列"
        }
      ]
    }
  ]
}
```

### 无展开按钮

设置成无展开按钮形式，通过事件动作控制展开关闭，可单独行控制。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/sample?perPage=5",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "id": "table-select",
      "columns": [
        {
          "title": "Engine",
          "name": "engine"
        },
        {
          "title": "Version",
          "name": "version"
        },
        {
          "title": "Browser",
          "name": "browser"
        },
        {
          "title": "Operation",
          "name": "operation",
          "type": "button",
          "label": "展开",
          "size": "sm",
          "onEvent": {
            "click": {
              "actions": [
                {
                  "actionType": "expand",
                  "componentId": "table-select",
                  "description": "展开行",
                  "args": {
                    "value": "${id}"
                  }
                }
              ]
            }
          }
        }
      ],
      "expandable": {
        "keyField": "id",
        "expandedRowClassNameExpr": "${ rowIndex % 2 ? 'bg-success' : '' }",
        "type": "container",
        "position": "none",
        "body": [
          {
            "type": "tpl",
            "html": "<div class=\"test\">测试测试</div>"
          }
        ]
      }
    }
  ]
}
```

也可以通过表达式一次控制多行展开关闭。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/sample?perPage=5",
  "body": [
    {
      "type": "container",
      "style": {
        "marginBottom": "5px"
      },
      "body": [
        {
          "type": "button",
          "label": "展开",
          "size": "sm",
          "onEvent": {
            "click": {
              "actions": [
                {
                  "actionType": "expand",
                  "componentId": "table-select2",
                  "description": "展开行",
                  "args": {
                    "expandedRowsExpr": "data.record?.id === 1 || data.record?.id === 3"
                  }
                }
              ]
            }
          }
        }
      ]
    },
    {
      "type": "table2",
      "source": "$rows",
      "id": "table-select2",
      "columns": [
        {
          "title": "Engine",
          "name": "engine"
        },
        {
          "title": "Version",
          "name": "version"
        },
        {
          "title": "Browser",
          "name": "browser"
        }
      ],
      "expandable": {
        "keyField": "id",
        "expandedRowClassNameExpr": "${ rowIndex % 2 ? 'bg-success' : '' }",
        "type": "container",
        "position": "none",
        "body": [
          {
            "type": "tpl",
            "html": "<div class=\"test\">测试测试</div>"
          }
        ]
      }
    }
  ]
}
```

## 表格行/列合并

可以通过设置`column.rowSpanExpr`来实现行合并，`column.colSpanExpr`来实现列合并。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/sample?perPage=10",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "columns": [
        {
          "title": "Engine",
          "name": "engine"
        },
        {
          "title": "Version",
          "name": "version",
          "rowSpanExpr": "${ rowIndex === 2 ? 2 : 0 }"
        },
        {
          "title": "Browser",
          "name": "browser"
        },
        {
          "title": "Badge",
          "name": "badgeText",
          "colSpanExpr": "${ rowIndex === 6 ? 3 : 0 }"
        },
        {
          "title": "Grade",
          "name": "grade"
        },
        {
          "title": "Platform",
          "name": "platform"
        }
      ]
    }
  ]
}
```

表头分组的情况下也是合并单元格，但包含分组的表头配置`column.rowSpanExpr`或者`column.colSpanExpr`无效。

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 固定表头

给`scroll.y`设置一个固定高度，当表格行数据超过该高度时，会自动出现滚动条。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/sample?perPage=10",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "scroll": {"y" : 200},
      "columns": [
        {
          "title": "Engine",
          "name": "engine"
        },
        {
          "title": "Grade",
          "name": "grade"
        },
        {
          "title": "Platform",
          "name": "platform"
        }
      ]
    }
  ]
}
```

## 固定列

如果列数足够多或者设置`scroll.x`一个超出表格可视范围的宽度，表格会自动出现横向滚动条，此时可以通过`column.fixed`来固定列，保证左右滑动的时候，一些关键列始终可见。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/sample?perPage=6",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "scroll": {"x": 1000},
      "columns": [
        {
          "title": "Engine",
          "name": "engine",
          "fixed": "left",
          "width": 100
        },
        {
          "title": "Version",
          "name": "version",
          "fixed": "left",
          "width": 100
        },
        {
          "title": "Browser",
          "name": "browser"
        },
        {
          "title": "Badge",
          "name": "badgeText"
        },
        {
          "title": "Grade",
          "name": "grade"
        },
        {
          "title": "Platform",
          "name": "platform",
          "fixed": "right"
        }
      ]
    }
  ]
}
```

## 固定头和列

同时设置`scroll.y`和`column.fixed`，内容超过可视范围，表格会自动出现横向、纵向滚动条，实现同时固定表头和指定列。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/sample?perPage=10",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "scroll": {"x": 1000, "y": 200},
      "columns": [
        {
          "title": "Engine",
          "name": "engine",
          "fixed": "left",
          "width": 100
        },
        {
          "title": "Version",
          "name": "version",
          "type": "property",
          "width": 400,
          "items": [
            {
              "label": "cpu",
              "content": "1 core"
            },
            {
              "label": "memory",
              "content": "4G"
            },
            {
              "label": "disk",
              "content": "80G"
            },
            {
              "label": "network",
              "content": "4M",
              "span": 2
            },
            {
              "label": "IDC",
              "content": "beijing"
            },
            {
              "label": "Note",
              "content": "其它说明",
              "span": 3
            }
          ]
        },
        {
          "title": "Browser",
          "name": "browser"
        },
        {
          "title": "Badge",
          "name": "badgeText"
        },
        {
          "title": "Grade",
          "name": "grade"
        },
        {
          "title": "Platform",
          "name": "platform",
          "fixed": "right"
        }
      ]
    }
  ]
}
```

## 表头分组

通过`column.children`可以设置表头分组，实现多级表头，可以任意组合多级嵌套。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/sample?perPage=10",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "scroll": {"y": 200},
      "columns": [
        {
          "title": "Engine",
          "name": "engine"
        },
        {
          "title": "Version",
          "name": "version"
        },
        {
          "title": "Grade",
          "name": "grade"
        },
        {
          "title": "Grade1",
          "name": "grade1",
          "children": [
            {
              "title": "Browser",
              "name": "browser"
            },
            {
              "title": "Badge",
              "name": "badgeText",
              "children": [
                {
                  "title": "ID",
                  "name": "id"
                }
              ]
            }
          ]
        },
        {
          "title": "Platform",
          "name": "platform"
        }
      ]
    }
  ]
}
```

`children`里的配置同`columns`，可以灵活组合，支持无限层级。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/sample?perPage=10",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "scroll": {"y": 200},
      "columns": [
        {
          "title": "Engine",
          "name": "engine"
        },
        {
          "title": "Version",
          "name": "version"
        },
        {
          "title": "Grade",
          "name": "grade",
          "colSpanExpr": "${ rowIndex === 1 ? 3 : 0 }"
        },
        {
          "title": "Grade1",
          "name": "grade1",
          "children": [
            {
              "title": "Browser",
              "name": "browser"
            }
          ]
        },
        {
          "title": "Platform1",
          "name": "platform1",
          "children": [
            {
              "title": "Badge1",
              "name": "badgeText1",
              "children": [
                {
                  "title": "ID",
                  "name": "id"
                },
                {
                  "title": "Platform",
                  "name": "platform"
                },
                {
                  "title": "Badge",
                  "name": "badgeText"
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}
```

## 拖拽排序

设置`draggable`为`true`，开启手动拖动排序。

### 默认拖拽排序

```schema: scope="body"
{
  "type": "service",
  "api": "/api/sample?perPage=5",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "draggable": true,
      "keyField": "id",
      "columns": [
        {
          "title": "ID",
          "name": "id"
        },
        {
          "title": "Grade",
          "name": "grade"
        },
        {
          "title": "Browser",
          "name": "browser"
        },
        {
          "title": "Badge",
          "name": "badgeText",
          "children": [
            {
              "title": "Engine",
              "name": "engine"
            }
          ]
        },
        {
          "title": "Platform",
          "name": "platform"
        }
      ]
    }
  ]
}
```

### 嵌套拖拽排序

数据源嵌套情况下，仅允许同层级之间排序。

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 总结栏

支持在表格的顶部或底部设置总结栏。

### 顶部单行

`headSummary`设置顶部导航栏，一维数组为单行，列数和表格列不一致的情况下，需要手动设置`colSpan`来保证总结栏展示和表格对应。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/sample?perPage=10",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "scroll": {"y": 200},
      "columns": [
        {
          "title": "Engine",
          "name": "engine"
        },
        {
          "title": "Version",
          "name": "version"
        },
        {
          "title": "Grade",
          "name": "grade"
        },
        {
          "title": "Browser",
          "name": "browser"
        },
        {
          "title": "Badge",
          "name": "badgeText"
        },
        {
          "title": "Platform",
          "name": "platform"
        }
      ],
      "headSummary": [
        {
          "type": "text",
          "text": "总计"
        },
        {
          "type": "tpl",
          "tpl": "测试测试",
          "colSpan": 5
        }
      ],
      "rowSelection": {
        "type": "checkbox",
        "keyField": "id"
      }
    }
  ]
}
```

### 顶部多行

`headSummary`设置为二维数组实现顶部多行。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/sample?perPage=10",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "scroll": {"y": 200},
      "columns": [
        {
          "title": "Engine",
          "name": "engine"
        },
        {
          "title": "Version",
          "name": "version"
        },
        {
          "title": "Grade",
          "name": "grade"
        },
        {
          "title": "Browser",
          "name": "browser"
        },
        {
          "title": "Badge",
          "name": "badgeText"
        },
        {
          "title": "Platform",
          "name": "platform"
        }
      ],
      "headSummary": [
        [
          {
            "type": "text",
            "text": "总计"
          },
          {
            "type": "tpl",
            "tpl": "测试测试",
            "colSpan": 5
          }
        ],
        [
          {
            "type": "text",
            "text": "总结",
            "colSpan": 6
          }
        ]
      ],
      "rowSelection": {
        "type": "checkbox",
        "keyField": "id"
      }
    }
  ]
}
```

### 尾部单行

`footSummary`设置尾部总结行，格式同`headSummary`。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/sample?perPage=10",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "bordered": true,
      "scroll": {"y": 200, "x": 1000},
      "columns": [
        {
          "title": "Engine",
          "name": "engine",
          "fixed": "left"
        },
        {
          "title": "Version",
          "name": "version"
        },
        {
          "title": "Grade",
          "name": "grade"
        },
        {
          "title": "Browser",
          "name": "browser"
        },
        {
          "title": "Badge",
          "name": "badgeText"
        },
        {
          "title": "Platform",
          "name": "platform"
        }
      ],
      "footSummary": [
        {
          "type": "text",
          "text": "总计",
          "fixed": 'left'
        },
        {
          "type": "tpl",
          "tpl": "测试测试",
          "colSpan": 5
        }
      ]
    }
  ]
}
```

### 尾部多行

如果二维数组中出现了非数组，那么认为是第一行的数据追加进去。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/sample?perPage=10",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "bordered": true,
      "scroll": {"y": 200, "x": 1000},
      "columns": [
        {
          "title": "Engine",
          "name": "engine",
          "fixed": "left"
        },
        {
          "title": "Version",
          "name": "version"
        },
        {
          "title": "Grade",
          "name": "grade"
        },
        {
          "title": "Browser",
          "name": "browser"
        },
        {
          "title": "Badge",
          "name": "badgeText"
        },
        {
          "title": "Platform",
          "name": "platform"
        }
      ],
      "footSummary": [
        {
          "type": "text",
          "text": "总计",
          "colSpan": 6
        },
        [
          {
            "type": "tpl",
            "tpl": "测试测试",
            "colSpan": 5
          },
          {
            "type": "text",
            "text": "总结",
            "colSpan": 1
          }
        ]
      ]
    }
  ]
}
```

## 调整列宽

通过设置`resizable`为`true`开启列宽调整功能，开启后可以手动拖动来调整某一列的宽度。

> 注意：`resizable`开启后，固定宽度的列无法拖动调整列宽

```schema: scope="body"
{
  "type": "service",
  "api": "/api/sample?perPage=6",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "scroll": {"x": 1000},
      "resizable": true,
      "columns": [
        {
          "title": "Engine",
          "name": "engine",
          "align": "center"
        },
        {
          "title": "Version",
          "name": "version",
          "width": 50,
          "align": "center"
        },
        {
          "title": "Grade",
          "name": "grade"
        },
        {
          "title": "Browser",
          "name": "browser"
        },
        {
          "title": "Badge",
          "name": "badgeText"
        },
        {
          "title": "Platform",
          "name": "platform"
        }
      ]
    }
  ]
}
```

## 自定义列

### 默认

可简单设置`columnsTogglable`为`true`快速开启自定义列功能，适用于列数较多的情况，可以手动控制展示或隐藏一些列。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/sample?perPage=6",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "columnsTogglable": true,
      "title": "表格的标题",
      "columns": [
        {
          "title": "Engine",
          "name": "engine",
          "width": 200
        },
        {
          "title": "Version",
          "name": "version",
          "width": 200
        },
        {
          "title": "Browser",
          "name": "browser",
          "width": 200,
          "children": [
            {
              "title": "Grade",
              "name": "grade",
              "width": 200
            }
          ]
        },
        {
          "title": "Badge",
          "name": "badgeText"
        },
        {
          "title": "Platform",
          "name": "platform"
        }
      ]
    }
  ]
}
```

### 自定义图标

如果默认的自定义列图标不能满足需求，可以通过设置`columnsTogglable.icon`来自定义图标。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/sample?perPage=6",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "columnsTogglable": {
        "icon": "fa fa-user"
      },
      "title": "表格的标题",
      "columns": [
        {
          "title": "Engine",
          "name": "engine",
          "width": 200
        },
        {
          "title": "Version",
          "name": "version",
          "width": 200
        },
        {
          "title": "Browser",
          "name": "browser",
          "width": 200,
          "children": [
            {
              "title": "Grade",
              "name": "grade",
              "width": 200
            }
          ]
        },
        {
          "title": "Badge",
          "name": "badgeText"
        },
        {
          "title": "Platform",
          "name": "platform"
        }
      ]
    }
  ]
}
```

## 数据为空

可以通过`placeholder`自定义数据为空时的展示内容，支持文本或者 schema 类型。

```schema
{
  "type": "table2",
  "data": {
    "items": []
  },
  "columns": [
    {
      "title": "Engine",
      "name": "engine",
      "width": 200
    },
    {
      "title": "Version",
      "name": "version",
      "width": 200
    },
    {
      "title": "Browser",
      "name": "browser",
      "width": 200,
      "children": [
        {
          "title": "Grade",
          "name": "grade",
          "width": 200
        }
      ]
    },
    {
      "title": "Platform",
      "name": "platform",
      "children": [
        {
          "title": "Badge",
          "name": "badgeText"
        }
      ]
    }
  ],
  "placeholder": "暂无数据"
}
```

## 数据加载中

可以通过`loading`自定义数据加载时的展示内容，支持布尔或者 schema 类型。

```schema
{
  "type": "table2",
  "data": {
    "items": []
  },
  "columns": [
    {
      "title": "Engine",
      "name": "engine",
      "width": 200
    },
    {
      "title": "Version",
      "name": "version",
      "width": 200
    },
    {
      "title": "Browser",
      "name": "browser",
      "width": 200,
      "children": [
        {
          "title": "Grade",
          "name": "grade",
          "width": 200
        },
        {
          "title": "Badge",
          "name": "badgeText",
          "children": [
            {
              "title": "Platform",
              "name": "platform"
            }
          ]
        }
      ]
    }
  ],
  "loading": true
}
```

## 树形结构

当行数据中存在 children 属性时，可以自动嵌套显示下去。也可以通过设置 childrenColumnName 进行配置。

### 默认嵌套

```
/* Detailed source-code truncated for AI context efficiency. */
```

### 多选嵌套

嵌套模式下表格支持多选的同时支持级联选中。

```
/* Detailed source-code truncated for AI context efficiency. */
```

### 单选嵌套

单选情况下，不同层级之间都是互斥选择。

```
/* Detailed source-code truncated for AI context efficiency. */
```

### 缩进设置

嵌套模式下可以通过`indentSize`来设置每一层级的缩进值。

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 列搜索

通过设置`column.searchable`为`true`快速开启列搜索功能。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/sample?perPage=6",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "columns": [
        {
          "title": "Engine",
          "name": "engine",
          "width": 200
        },
        {
          "title": "Version",
          "name": "version",
          "width": 200,
          "searchable": true
        },
        {
          "title": "Browser",
          "name": "browser",
          "width": 200,
          "children": [
            {
              "title": "Grade",
              "name": "grade",
              "width": 200
            }
          ]
        },
        {
          "title": "Badge",
          "name": "badgeText"
        },
        {
          "title": "Platform",
          "name": "platform"
        }
      ]
    }
  ]
}
```

## 粘性头部

设置`sticky`为`true`开启粘性头部。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/sample?perPage=6",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "title": "表格的标题",
      "columns": [
        {
          "title": "Engine",
          "name": "engine",
          "width": 200
        },
        {
          "title": "Version",
          "name": "version",
          "width": 200
        },
        {
          "title": "Browser",
          "name": "browser",
          "width": 200,
          "children": [
            {
              "title": "Grade",
              "name": "grade",
              "width": 200
            }
          ]
        },
        {
          "title": "Badge",
          "name": "badgeText"
        },
        {
          "title": "Platform",
          "name": "platform"
        }
      ],
      "sticky": true
    }
  ]
}
```

## 表格尺寸

通过设置`size`属性来控制表格尺寸，支持`large`、`default`、`small`，`default`是中等尺寸。

### 最大尺寸

`large`是最大尺寸。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/sample?perPage=6",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "size": "large",
      "rowSelection": {
        "type": "checkbox",
        "keyField": "id"
      },
      "columns": [
        {
          "title": "Engine",
          "name": "engine",
          "sorter": true,
          "tpl": "${engine|truncate:5}"
        },
        {
          "title": "Version",
          "name": "version",
          "sorter": true,
          "filterMultiple": true,
          "filters": [
            {
              "text": "Joe",
              "value": "Joe"
            },
            {
              "text": "Jim",
              "value": "Jim"
            }
          ]
        },
        {
          "type": "tpl",
          "title": "Browser",
          "name": "browser",
          "tpl": "${browser|truncate:5}",
          "searchable": true
        },
        {
          "title": "Badge",
          "name": "badgeText"
        },
        {
          "title": "Platform",
          "name": "platform"
        }
      ],
      "footSummary": [
        {
          "type": "text",
          "text": "总计",
          "fixed": "left"
        },
        {
          "type": "tpl",
          "tpl": "测试测试",
          "colSpan": 5
        }
      ]
    }
  ]
}
```

### 默认尺寸

默认尺寸是`default`，即中等尺寸。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/sample?perPage=6",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "rowSelection": {
        "type": "checkbox",
        "keyField": "id"
      },
      "columns": [
        {
          "title": "Engine",
          "name": "engine",
          "sorter": true,
          "tpl": "${engine|truncate:5}"
        },
        {
          "title": "Version",
          "name": "version",
          "sorter": true,
          "filterMultiple": true,
          "filters": [
            {
              "text": "Joe",
              "value": "Joe"
            },
            {
              "text": "Jim",
              "value": "Jim"
            }
          ]
        },
        {
          "type": "tpl",
          "title": "Browser",
          "name": "browser",
          "tpl": "${engine|truncate:5}",
          "searchable": true
        },
        {
          "title": "Badge",
          "name": "badgeText"
        },
        {
          "title": "Platform",
          "name": "platform"
        }
      ],
      "footSummary": [
        {
          "type": "text",
          "text": "总计",
          "fixed": "left"
        },
        {
          "type": "tpl",
          "tpl": "测试测试",
          "colSpan": 5
        }
      ]
    }
  ]
}
```

### 小尺寸

`size`设置为`small`是最小尺寸。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/sample?perPage=6",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "size": "small",
      "rowSelection": {
        "type": "checkbox",
        "keyField": "id"
      },
      "columns": [
        {
          "title": "Engine",
          "name": "engine",
          "sorter": true,
          "tpl": "${engine|truncate:5}"
        },
        {
          "title": "Version",
          "name": "version",
          "sorter": true,
          "filterMultiple": true,
          "filters": [
            {
              "text": "Joe",
              "value": "Joe"
            },
            {
              "text": "Jim",
              "value": "Jim"
            }
          ]
        },
        {
          "type": "tpl",
          "title": "Browser",
          "name": "browser",
          "tpl": "${engine|truncate:5}",
          "searchable": true
        },
        {
          "title": "Badge",
          "name": "badgeText"
        },
        {
          "title": "Platform",
          "name": "platform"
        }
      ],
      "footSummary": [
        {
          "type": "text",
          "text": "总计",
          "fixed": "left"
        },
        {
          "type": "tpl",
          "tpl": "测试测试",
          "colSpan": 5
        }
      ]
    }
  ]
}
```

## 可复制

给列配置`copyable`属性即可开启列内容复制功能。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/sample?perPage=6",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "title": "表格的标题",
      "columns": [
        {
          "title": "Engine",
          "name": "engine",
          "width": 200
        },
        {
          "title": "Version",
          "name": "version",
          "copyable": true
        },
        {
          "title": "Browser",
          "name": "browser",
          "width": 200
        },
        {
          "title": "Badge",
          "name": "badgeText"
        },
        {
          "title": "Platform",
          "name": "platform"
        }
      ]
    }
  ]
}
```

## 弹出框

可以给列配置上`popOver`属性，默认会在该列内容区里渲染一个图标，点击会显示弹出框，用于展示全部内容。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/sample?perPage=6",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "columns": [
        {
          "title": "Engine",
          "name": "engine"
        },
        {
          "title": "Version",
          "name": "version"
        },
        {
          "title": "Browser",
          "name": "browser",
          "copyable": true,
          "popOver": {
            "body": {
              "type": "tpl",
              "tpl": "详细信息：${browser}"
            }
          }
        },
        {
          "title": "Badge",
          "name": "badgeText"
        },
        {
          "title": "Platform",
          "name": "platform"
        }
      ]
    }
  ]
}
```

也可以设置图标不展示，结合`truncate`实现内容自动省略，其余可点击/悬浮查看更多。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/sample?perPage=6",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "columns": [
        {
          "title": "Engine",
          "name": "engine"
        },
        {
          "title": "Version",
          "name": "version"
        },
        {
          "type": "tpl",
          "title": "Browser",
          "name": "browser",
          "tpl": "${engine|truncate:5}",
          "popOver": {
            "trigger": "hover",
            "position": "left-top",
            "showIcon": false,
            "body": {
              "type": "tpl",
              "tpl": "${browser}"
            }
          }
        },
        {
          "title": "Badge",
          "name": "badgeText"
        },
        {
          "title": "Platform",
          "name": "platform"
        }
      ]
    }
  ]
}
```

可以给列配置上`textOverflow`属性，设置为`ellipsis`，可实现内容超出省略，悬浮查看更多。
可搭配`popOver`属性，来控制弹出框的信息，需要设置图标不展示。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/sample?perPage=6",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "columns": [
        {
          "title": "Engine",
          "name": "engine",
        },
        {
          "title": "Version",
          "name": "version"
        },
        {
          "type": "tpl",
          "title": "Browser",
          "name": "browser",
          "tpl": "${browser+'--'+browser}",
          "textOverflow": "ellipsis",
          "popOver": {
            "trigger": "hover",
            "position": "right-top-center-bottom",
            "showIcon": false,
            "body": {
              "type": "tpl",
              "tpl": "${browser}"
            }
          }
        },
        {
          "title": "Badge",
          "name": "badgeText"
        },
        {
          "title": "Platform",
          "name": "platform"
        }
      ]
    }
  ]
}
```

可以给列配置`popOverEnableOn`属性，该属性为表达式，来控制当前行是否启动`popOver`功能。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/sample?perPage=6",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "columns": [
        {
          "title": "ID",
          "name": "id",
          "popOver": {
            "body": {
              "type": "tpl",
              "tpl": "${id}"
            }
          },
          "popOverEnableOn": "this.id == 1"
        },
        {
          "title": "Engine",
          "name": "engine"
        },
        {
          "title": "Version",
          "name": "version"
        },
        {
          "title": "Browser",
          "name": "browser",
          "popOver": {
            "body": {
              "type": "tpl",
              "tpl": "${browser}"
            }
          }
        },
        {
          "title": "Badge",
          "name": "badgeText"
        },
        {
          "title": "Platform",
          "name": "platform"
        }
      ]
    }
  ]
}
```

## 行角标

通过属性`itemBadge`，可以为表格行配置[角标](./badge)，可以使用[数据映射](../../../docs/concepts/data-mapping)为每一行添加特定的 Badge 属性。[`visibleOn`](../../../docs/concepts/expression)属性控制显示的条件，表达式中`this`可以取到行所在上下文的数据，比如行数据中有`badgeText`字段才显示角标，可以设置`"visibleOn": "this.badgeText"`。

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 表头提示

通过设置列属性`remark`，可为每一列的表头增加提示信息。

```schema: scope="body"
{
  "type": "page",
  "body": {
    "type": "service",
    "api": "/api/sample?perPage=5",
    "body": [
      {
        "type": "table2",
        "source": "$rows",
        "columns": [
          {
            "title": "Engine",
            "name": "engine",
            "remark": "表头提示"
          },
          {
            "title": "Version",
            "name": "version"
          },
          {
            "title": "Browser",
            "name": "browser"
          },
          {
            "title": "Badge",
            "name": "badgeText"
          },
          {
            "title": "Grade",
            "name": "grade"
          },
          {
            "title": "Platform",
            "name": "platform"
          }
        ]
      }
    ]
  }
}
```

## 快速编辑

可以通过给列配置：`"quickEdit": true`，Table 配置：`quickSaveApi`，可以实现表格内快速编辑并批量保存的功能。

```schema: scope="body"
{
  "type": "page",
  "body": {
    "type": "service",
    "api": "/api/sample?perPage=5",
    "id": "service-container",
    "body": [
      {
        "type": "table2",
        "source": "$rows",
        "quickSaveApi": {
          "url": "/api/mock2/sample/bulkUpdate",
          "method": "put"
        },
        "draggable": true,
        "onEvent": {
          "quickSaveSubmitted": {
            "actions": [
              {
                "actionType": "reload",
                "componentId": "service-container"
              }
            ]
          },
          "orderChange": {
            "actions": [
              {
                "actionType": "reload",
                "componentId": "service-container"
              }
            ]
          }
        },
        "columns": [
          {
            "title": "Engine",
            "name": "engine",
            "quickEdit": true
          },
          {
            "title": "Version",
            "name": "version"
          },
          {
            "title": "Browser",
            "name": "browser"
          },
          {
            "title": "Badge",
            "name": "badgeText"
          }
        ]
      }
    ]
  }
}
```

#### 指定编辑表单项类型

`quickEdit`也可以配置对象形式，可以指定编辑表单项的类型，例如`"type": "select"`。

```schema: scope="body"
{
  "type": "page",
  "body": {
    "type": "service",
    "api": "/api/sample?perPage=5",
    "body": [
      {
        "type": "table2",
        "source": "$rows",
        "quickSaveApi": {
          "url": "/api/mock2/sample/bulkUpdate",
          "method": "put"
        },
        "columns": [
          {
            "name": "id",
            "title": "ID"
          },
          {
            "name": "grade",
            "title": "CSS grade",
            "quickEdit": {
              "type": "select",
              "options": [
                "A",
                "B",
                "C",
                "D",
                "X"
              ]
            }
          }
        ]
      }
    ]
  }
}
```

#### 快速编辑多个表单项

```schema: scope="body"
{
  "type": "page",
  "body": {
    "type": "service",
    "api": "/api/sample?perPage=5",
    "body": [
      {
        "type": "table2",
        "source": "$rows",
        "quickSaveApi": {
          "url": "/api/mock2/sample/bulkUpdate",
          "method": "put"
        },
        "columns": [
          {
            "name": "id",
            "title": "ID"
          },
          {
            "name": "grade",
            "title": "CSS grade",
            "quickEdit": {
              "body": [
                {
                  "type": "select",
                  "name": "grade",
                  "options": [
                    "A",
                    "B",
                    "C",
                    "D",
                    "X"
                  ]
                },
                {
                  "label": "id",
                  "type": "input-text",
                  "name": "id"
                }
              ]
            }
          }
        ]
      }
    ]
  }
}
```

#### 内联模式

配置`quickEdit`的`mode`为`inline`。可以直接将编辑表单项渲染至表格内，可以直接操作编辑。

```schema: scope="body"
{
  "type": "page",
  "body": {
    "type": "service",
    "api": "/api/sample?perPage=5",
    "body": [
      {
        "type": "table2",
        "source": "$rows",
        "quickSaveApi": {
          "url": "/api/mock2/sample/bulkUpdate",
          "method": "put"
        },
        "columns": [
          {
            "name": "id",
            "title": "ID"
          },
          {
            "name": "grade",
            "title": "CSS grade",
            "quickEdit": {
              "mode": "inline",
              "type": "select",
              "size": "xs",
              "options": [
                "A",
                "B",
                "C",
                "D",
                "X"
              ]
            }
          },
          {
            "name": "switch",
            "title": "switch",
            "quickEdit": {
              "mode": "inline",
              "type": "switch",
              "onText": "开启",
              "offText": "关闭"
            }
          }
        ]
      }
    ]
  }
}
```

#### 即时保存

如果想编辑完表单项之后，不想点击顶部确认按钮来进行保存，而是即时保存当前标记的数据，则需要配置 `quickEdit` 中的 `"saveImmediately": true`，然后配置接口`quickSaveItemApi`，可以直接将编辑表单项渲染至表格内操作。

```schema: scope="body"
{
  "type": "page",
  "body": {
    "type": "service",
    "api": "/api/sample?perPage=5",
    "body": [
      {
        "type": "table2",
        "source": "$rows",
        "quickSaveItemApi": {
          "url": "/api/mock2/sample/$id",
          "method": "put"
        },
        "columns": [
          {
            "name": "id",
            "title": "ID"
          },
          {
            "name": "grade",
            "title": "CSS grade",
            "quickEdit": {
              "mode": "inline",
              "type": "select",
              "size": "xs",
              "options": [
                "A",
                "B",
                "C",
                "D",
                "X"
              ],
              "saveImmediately": true
            }
          },
          {
            "name": "switch",
            "title": "switch",
            "quickEdit": {
              "mode": "inline",
              "type": "switch",
              "onText": "开启",
              "offText": "关闭",
              "saveImmediately": true
            }
          }
        ]
      }
    ]
  }
}
```

你也可以在`saveImmediately`中配置 api，实现即时保存。

```schema: scope="body"
{
  "type": "page",
  "body": {
    "type": "service",
    "api": "/api/sample?perPage=5",
    "body": [
      {
        "type": "table2",
        "source": "$rows",
        "columns": [
          {
            "name": "id",
            "title": "ID"
          },
          {
            "name": "grade",
            "title": "CSS grade",
            "quickEdit": {
              "mode": "inline",
              "type": "select",
              "size": "xs",
              "options": [
                "A",
                "B",
                "C",
                "D",
                "X"
              ],
              "saveImmediately": {
                "api": "/api/mock2/sample/$id"
              }
            }
          },
          {
            "name": "switch",
            "title": "switch",
            "quickEdit": {
              "mode": "inline",
              "type": "switch",
              "onText": "开启",
              "offText": "关闭",
              "saveImmediately": {
                "api": "/api/mock2/sample/$id"
              }
            }
          }
        ]
      }
    ]
  }
}
```

## 列样式

可以通过设置`columns`中的`className`控制整列样式。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/sample?perPage=5",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "columns": [
        {
          "title": "Engine",
          "name": "engine"
        },
        {
          "title": "Version",
          "name": "version",
          "className": "text-primary"
        },
        {
          "title": "Browser",
          "name": "browser"
        },
        {
          "title": "Operation",
          "name": "operation",
          "type": "button",
          "label": "删除",
          "size": "sm"
        }
      ]
    }
  ]
}
```

也可以通过`titleClassName`单独控制表头对应单元格的样式。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/sample?perPage=5",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "columns": [
        {
          "title": "Engine",
          "name": "engine"
        },
        {
          "title": "Version",
          "name": "version",
          "className": "text-primary",
          "titleClassName": "font-bold"
        },
        {
          "title": "Browser",
          "name": "browser"
        },
        {
          "title": "Operation",
          "name": "operation",
          "type": "button",
          "label": "删除",
          "size": "sm"
        }
      ]
    }
  ]
}
```

## 单元格样式

可以通过设置`columns`的`classNameExpr`，根据数据动态添加单元格 CSS 类，支持模版语法。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/sample?perPage=5",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "columns": [
        {
          "title": "Engine",
          "name": "engine"
        },
        {
          "title": "Version",
          "name": "version",
          "classNameExpr": "${ version > 5 ? 'text-danger' : '' }"
        },
        {
          "title": "Browser",
          "name": "browser"
        },
        {
          "title": "Operation",
          "name": "operation",
          "type": "button",
          "label": "删除",
          "size": "sm"
        }
      ]
    }
  ]
}
```

## 行操作按钮

通过设置`itemActions`可以设置鼠标移动到行上出现操作按钮。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/sample?perPage=5",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "itemActions": [
        {
          "label": "编辑",
          "type": "button",
          "actionType": "dialog",
          "dialog": {
            "title": "编辑",
            "body": "这是个简单的编辑弹框"
          }
        },
        {
          "label": "删除",
          "type": "button",
          "actionType": "ajax",
          "confirmText": "确认要删除？",
          "api": "/api/mock2/form/saveForm"
        }
      ],
      "columns": [
        {
          "title": "Engine",
          "name": "engine"
        },
        {
          "title": "Version",
          "name": "version"
        }
      ]
    }
  ]
}
```

固定表头情况下，展示行操作按钮。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/sample?perPage=20",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "itemActions": [
        {
          "label": "编辑",
          "type": "button",
          "actionType": "dialog",
          "dialog": {
            "title": "编辑",
            "body": "这是个简单的编辑弹框"
          }
        },
        {
          "label": "删除",
          "type": "button",
          "actionType": "ajax",
          "confirmText": "确认要删除？",
          "api": "/api/mock2/form/saveForm"
        }
      ],
      "scroll": {
        "y": 100
      },
      "columns": [
        {
          "title": "Engine",
          "name": "engine"
        },
        {
          "title": "Version",
          "name": "version"
        }
      ]
    }
  ]
}
```

## 属性表

| 属性名           | 类型                                                     | 默认值                    | 说明                                                                      |
| ---------------- | -------------------------------------------------------- | ------------------------- | ------------------------------------------------------------------------- |
| type             | `string`                                                 |                           | `"type"` 指定为 table 渲染器                                              |
| title            | `string`                                                 |                           | 标题                                                                      |
| source           | `string`                                                 | `${items}`                | 数据源, 绑定当前环境变量                                                  |
| sticky           | `boolean`                                                | `false`                   | 是否粘性头部                                                              |
| footer           | `string` \| `Schema`                                     |                           | 表格尾部                                                                  |
| loading          | `boolean`                                                |                           | 表格是否加载中                                                            |
| columnsTogglable | `auto` 或者 `boolean`                                    | `auto`                    | 展示列显示开关, 自动即：列数量大于或等于 5 个时自动开启                   |
| placeholder      | `string` \| `Schema`                                     | `暂无数据`                | 当没数据的时候的文字提示                                                  |
| rowSelection     | `rowSelection`                                           |                           | 行相关配置                                                                |
| rowClassNameExpr | `string`                                                 |                           | 行 CSS 类名，支持模版语法                                                 |
| expandable       | `Expandable`                                             |                           | 展开行配置                                                                |
| lineHeight       | `large` \| `middle`                                      |                           | 行高设置                                                                  |
| footerClassName  | `string`                                                 | `Action.md-table-footer`  | 底部外层 CSS 类名                                                         |
| toolbarClassName | `string`                                                 | `Action.md-table-toolbar` | 工具栏 CSS 类名                                                           |
| columns          | `Array<Column>`                                          |                           | 用来设置列信息                                                            |
| itemActions      | Array<[Action](./action-button)>                         |                           | 悬浮行操作按钮组                                                          |
| itemCheckableOn  | [表达式](../../docs/concepts/expression)                 |                           | 配置当前行是否可勾选的条件，要用 [表达式](../../docs/concepts/expression) |
| itemDraggableOn  | [表达式](../../docs/concepts/expression)                 |                           | 配置当前行是否可拖拽的条件，要用 [表达式](../../docs/concepts/expression) |
| checkOnItemClick | `boolean`                                                | `false`                   | 点击数据行是否可以勾选当前行                                              |
| rowClassName     | `string`                                                 |                           | 给行添加 CSS 类名                                                         |
| rowClassNameExpr | [模板](../../docs/concepts/template)                     |                           | 通过模板给行添加 CSS 类名                                                 |
| prefixRow        | `Array`                                                  |                           | 顶部总结行                                                                |
| affixRow         | `Array`                                                  |                           | 底部总结行                                                                |
| itemBadge        | [`BadgeSchema`](./badge)                                 |                           | 行角标配置                                                                |
| autoFillHeight   | `boolean` 丨 `{height: number}` 丨 `{maxHeight: number}` |                           | 内容区域自适应高度，可选择自适应、固定高度和最大高度                      |
| lazyRenderAfter  | `number`                                                 | 100                       | 默认数据超过 100 条启动懒加载提升渲染性能，也可通过自定义该属性调整数值   |

## 行配置属性表

| 属性名              | 类型                               | 默认值     | 说明                                                                                                               |
| ------------------- | ---------------------------------- | ---------- | ------------------------------------------------------------------------------------------------------------------ |
| type                | `checkbox` \| `radio`              | `checkbox` | 指定单选还是多选                                                                                                   |
| fixed               | `boolean`                          |            | 选择列是否固定，只能左侧固定                                                                                       |
| keyField            | `string`                           | `key`      | 对应数据源的 key 值，默认是`key`，可指定为`id`、`shortId`等                                                        |
| disableOn           | `string`                           |            | 当前行是否可选择条件，要用 [表达式](../../docs/concepts/expression)                                                |
| selections          | `selections`                       |            | 自定义筛选菜单，内置`all`（全选）、`invert`（反选）、`none`（取消选择）、`odd`（选择奇数项）、`even`（选择偶数项） |
| selectedRowKeys     | `Array<string>` \| `Array<number>` |            | 已选择项                                                                                                           |
| selectedRowKeysExpr | `string`                           |            | 已选择项表达式                                                                                                     |
| columnWidth         | `number`                           |            | 自定义选择列列宽                                                                                                   |
| rowClick            | `boolean`                          |            | 单条任意区域选中                                                                                                   |
| rowClickIgControl   | `boolean`                          |            | 点击控件时也会触发 rowClick 事件                                                                                   |

### 选择菜单配置属性表

| 属性名 | 类型                                           | 默认值 | 说明                                                       |
| ------ | ---------------------------------------------- | ------ | ---------------------------------------------------------- |
| key    | `all` \| `invert` \| `none` \| `odd` \| `even` | `all`  | 菜单类型，内置全选、反选、取消选择、选择奇数项、选择偶数项 |
| text   | `string`                                       |        | 自定义菜单项文本                                           |

## 展开行配置属性表

| 属性名              | 类型                               | 默认值 | 说明                                                                                                               |
| ------------------- | ---------------------------------- | ------ | ------------------------------------------------------------------------------------------------------------------ |
| expandableOn        | `string`                           |        | 指定可展开的行，要用 [表达式](../../docs/concepts/expression)                                                      |
| keyField            | `string`                           | `key`  | 对应数据源的 key 值，默认是`key`，可指定为`id`、`shortId`等                                                        |
| disableOn           | `string`                           |        | 当前行是否可选择条件，要用 [表达式](../../docs/concepts/expression)                                                |
| selections          | `selections`                       |        | 自定义筛选菜单，内置`all`（全选）、`invert`（反选）、`none`（取消选择）、`odd`（选择奇数项）、`even`（选择偶数项） |
| selectedRowKeys     | `Array<string>` \| `Array<number>` |        | 已选择项                                                                                                           |
| selectedRowKeysExpr | `string`                           |        | 已选择项表达式                                                                                                     |
| columnWidth         | `number`                           |        | 自定义选择列列宽                                                                                                   |

## 列配置属性表

| 属性名       | 类型                                          | 默认值    | 说明                                                                                                           |
| ------------ | --------------------------------------------- | --------- | -------------------------------------------------------------------------------------------------------------- |
| label        | [模板](../../docs/concepts/template)          |           | 表头文本内容                                                                                                   |
| name         | `string`                                      |           | 通过名称关联数据                                                                                               |
| fixed        | `left` \| `right` \| `none`                   |           | 是否固定当前列                                                                                                 |
| popOver      |                                               |           | 弹出框                                                                                                         |
| quickEdit    |                                               |           | 快速编辑                                                                                                       |
| copyable     | `boolean` 或 `{icon: string, content:string}` |           | 是否可复制                                                                                                     |
| sortable     | `boolean`                                     | `false`   | 是否可排序                                                                                                     |
| searchable   | `boolean` \| `Schema`                         | `false`   | 是否可快速搜索                                                                                                 |
| width        | `number` \| `string`                          | 列宽      |
| remark       |                                               |           | 提示信息                                                                                                       |
| textOverflow | `string`                                      | `default` | 文本溢出后展示形式，默认换行处理。可选值 `ellipsis` 溢出隐藏展示， `noWrap` 不换行展示(仅在列为静态文本时生效) |

## 事件表

当前组件会对外派发以下事件，可以通过`onEvent`来监听这些事件，并通过`actions`来配置执行的动作，在`actions`中可以通过`${事件参数名}`或`${event.data.[事件参数名]}`来获取事件产生的数据，详细查看[事件动作](../../docs/concepts/event-action)。

| 事件名称           | 事件参数                                                                                  | 说明                             |
| ------------------ | ----------------------------------------------------------------------------------------- | -------------------------------- |
| selectedChange     | `selectedItems: item[]` 已选择行<br/>`unSelectedItems: item[]` 未选择行                   | 手动选择表格项时触发             |
| columnSort         | `orderBy: string` 列排序列名<br/>`orderDir: string` 列排序值                              | 点击列排序时触发                 |
| columnFilter       | `filterName: string` 列筛选列名<br/>`filterValue: string` 列筛选值                        | 点击列筛选时触发                 |
| columnSearch       | `searchName: string` 列搜索列名<br/>`searchValue: string` 列搜索数据                      | 点击列搜索时触发                 |
| orderChange        | `movedItems: item[]` 已排序数据                                                           | 手动拖拽行排序时触发             |
| columnToggled      | `columns: item[]` 当前显示的列配置数据                                                    | 点击自定义列时触发               |
| rowClick           | `item: object` 行点击数据<br/>`index: number` 行索引                                      | 单击整行时触发                   |
| rowDbClick         | `item: object` 行点击数据<br/>`index: number` 行索引                                      | 双击整行时触发                   |
| rowMouseEnter      | `item: object` 行移入数据<br/>`index: number` 行索引                                      | 移入整行时触发                   |
| rowMouseLeave      | `item: object` 行移出数据<br/>`index: number` 行索引                                      | 移出整行时触发                   |
| quickSaveSubmitted | `item: object` 快速编辑相关数据，包括源数据、修改后的数据、修改的行数索引、没有变动的数据 | 成功调用 `quickSaveApi` 之后触发 |

### selectedChange

在开启批量操作后才会用到，可以尝试勾选列表的行记录。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/mock2/sample?perPage=10",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "selectable": true,
      "onEvent": {
        "selectedChange": {
          "actions": [
            {
              "actionType": "toast",
              "args": {
                "msg": "已选择${event.data.selectedItems.length}条记录"
              }
            }
          ]
        }
      },
      "columns": [
        {
          "name": "id",
          "label": "ID"
        },
        {
          "name": "engine",
          "label": "Rendering engine"
        },
        {
          "name": "browser",
          "label": "Browser"
        },
        {
          "name": "platform",
          "label": "Platform(s)"
        },
        {
          "name": "version",
          "label": "Engine version"
        },
        {
          "name": "grade",
          "label": "CSS grade"
        }
      ]
    }
  ]
}
```

### columnSort

列排序，可以尝试点击`Browser`列右侧的排序图标。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/mock2/sample?perPage=10",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "onEvent": {
        "columnSort": {
          "actions": [
            {
              "actionType": "toast",
              "args": {
                "msgType": "info",
                "msg": "orderBy：${event.data.orderBy},orderDir：${event.data.orderDir}"
              }
            }
          ]
        }
      },
      "columns": [
        {
          "name": "id",
          "label": "ID",
          "searchable": true
        },
        {
          "name": "engine",
          "label": "Rendering engine",
          "filterable": {
            "options": [
              "Internet Explorer 4.0",
              "Internet Explorer 5.0"
            ]
          }
        },
        {
          "name": "browser",
          "label": "Browser",
          "sortable": true
        },
        {
          "name": "platform",
          "label": "Platform(s)"
        },
        {
          "name": "version",
          "label": "Engine version"
        },
        {
          "name": "grade",
          "label": "CSS grade"
        }
      ]
    }
  ]
}
```

### columnFilter

列过滤，可以尝试点击`Rendering engine`列右侧的筛选图标。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/mock2/sample?perPage=10",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "onEvent": {
        "columnFilter": {
          "actions": [
            {
              "actionType": "toast",
              "args": {
                "msgType": "info",
                "msg": "filterName：${event.data.filterName},filterValue：${event.data.filterValue}"
              }
            }
          ]
        }
      },
      "columns": [
        {
          "name": "id",
          "label": "ID",
          "searchable": true
        },
        {
          "name": "engine",
          "label": "Rendering engine",
          "filterable": {
            "options": [
              "Internet Explorer 4.0",
              "Internet Explorer 5.0"
            ]
          }
        },
        {
          "name": "browser",
          "label": "Browser",
          "sortable": true
        },
        {
          "name": "platform",
          "label": "Platform(s)"
        },
        {
          "name": "version",
          "label": "Engine version"
        },
        {
          "name": "grade",
          "label": "CSS grade"
        }
      ]
    }
  ]
}
```

### columnSearch

列检索，，可以尝试点击`ID`列右侧的检索图标。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/mock2/sample?perPage=10",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "onEvent": {
        "columnSearch": {
          "actions": [
            {
              "actionType": "toast",
              "args": {
                "msgType": "info",
                "msg": "searchName：${event.data.searchName},searchValue：${event.data.searchValue|json}"
              }
            }
          ]
        }
      },
      "columns": [
        {
          "name": "id",
          "label": "ID",
          "searchable": true
        },
        {
          "name": "engine",
          "label": "Rendering engine",
          "filterable": {
            "options": [
              "Internet Explorer 4.0",
              "Internet Explorer 5.0"
            ]
          }
        },
        {
          "name": "browser",
          "label": "Browser",
          "sortable": true
        },
        {
          "name": "platform",
          "label": "Platform(s)"
        },
        {
            "name": "version",
            "label": "Engine version"
        },
        {
          "name": "grade",
          "label": "CSS grade"
        }
      ]
    }
  ]
}
```

### columnToggled

点击自定义列，可以尝试修改`自定义列`的配置。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/mock2/sample?perPage=10",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "onEvent": {
        "columnToggled": {
          "actions": [
            {
              "actionType": "toast",
              "args": {
                "msgType": "info",
                "msg": "当前显示${event.data.columns.length}列"
              }
            }
          ]
        }
      },
      "columns": [
        {
          "name": "id",
          "label": "ID",
          "searchable": true
        },
        {
          "name": "engine",
          "label": "Rendering engine",
          "filterable": {
            "options": [
              "Internet Explorer 4.0",
              "Internet Explorer 5.0"
            ]
          }
        },
        {
          "name": "browser",
          "label": "Browser",
          "sortable": true
        },
        {
          "name": "platform",
          "label": "Platform(s)"
        },
        {
          "name": "version",
          "label": "Engine version"
        },
        {
          "name": "grade",
          "label": "CSS grade"
        }
      ]
    }
  ]
}
```

### orderChange

在开启拖拽排序行记录后才会用到，排序确认后触发。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/mock2/sample?perPage=10",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "draggable": true,
      "onEvent": {
        "orderChange": {
          "actions": [
            {
              "actionType": "toast",
              "args": {
                "msgType": "info",
                "msg": "${event.data.movedItems.length}行发生移动"
              }
            }
          ]
        }
      },
      "columns": [
        {
          "name": "id",
          "label": "ID",
          "searchable": true
        },
        {
          "name": "engine",
          "label": "Rendering engine",
          "filterable": {
            "options": [
              "Internet Explorer 4.0",
              "Internet Explorer 5.0"
            ]
          }
        },
        {
          "name": "browser",
          "label": "Browser",
          "sortable": true
        },
        {
          "name": "platform",
          "label": "Platform(s)"
        },
        {
          "name": "version",
          "label": "Engine version"
        },
        {
          "name": "grade",
          "label": "CSS grade"
        }
      ]
    }
  ]
}
```

### rowClick

点击行记录。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/mock2/sample?perPage=10",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "selectable": true,
      "onEvent": {
        "rowClick": {
          "actions": [
            {
              "actionType": "toast",
              "args": {
                "msgType": "info",
                "msg": "行单击数据：${event.data.item|json}；行索引：${event.data.index}"
              }
            }
          ]
        }
      },
      "columns": [
        {
          "name": "id",
          "label": "ID",
          "searchable": true
        },
        {
          "name": "engine",
          "label": "Rendering engine",
          "filterable": {
            "options": [
              "Internet Explorer 4.0",
              "Internet Explorer 5.0"
            ]
          }
        },
        {
          "name": "browser",
          "label": "Browser",
          "sortable": true
        },
        {
          "name": "platform",
          "label": "Platform(s)"
        },
        {
          "name": "version",
          "label": "Engine version"
        },
        {
          "name": "grade",
          "label": "CSS grade"
        }
      ]
    }
  ]
}
```

### rowDbClick

双击整行时触发。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/mock2/sample?perPage=10",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "onEvent": {
        "rowDbClick": {
          "actions": [
            {
              "actionType": "toast",
              "args": {
                "msgType": "info",
                "msg": "行双击数据：${event.data.item|json}；行索引：${event.data.index}"
              }
            }
          ]
        }
      },
      "columns": [
        {
          "name": "id",
          "label": "ID",
          "searchable": true
        },
        {
          "name": "engine",
          "label": "Rendering engine",
          "filterable": {
            "options": [
              "Internet Explorer 4.0",
              "Internet Explorer 5.0"
            ]
          }
        },
        {
          "name": "browser",
          "label": "Browser",
          "sortable": true
        },
        {
          "name": "platform",
          "label": "Platform(s)"
        },
        {
          "name": "version",
          "label": "Engine version"
        },
        {
          "name": "grade",
          "label": "CSS grade"
        }
      ]
    }
  ]
}
```

### rowMouseEnter

鼠标移入行记录。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/mock2/sample?perPage=10",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "onEvent": {
        "rowMouseEnter": {
          "actions": [
            {
              "actionType": "toast",
              "args": {
                "msgType": "info",
                "msg": "行索引：${event.data.index}"
              }
            }
          ]
        }
      },
      "columns": [
        {
          "name": "id",
          "label": "ID",
          "searchable": true
        },
        {
          "name": "engine",
          "label": "Rendering engine",
          "filterable": {
            "options": [
              "Internet Explorer 4.0",
              "Internet Explorer 5.0"
            ]
          }
        },
        {
          "name": "browser",
          "label": "Browser",
          "sortable": true
        },
        {
          "name": "platform",
          "label": "Platform(s)"
        },
        {
          "name": "version",
          "label": "Engine version"
        },
        {
          "name": "grade",
          "label": "CSS grade"
        }
      ]
    }
  ]
}
```

### rowMouseLeave

鼠标移出行记录。

```schema: scope="body"
{
  "type": "service",
  "api": "/api/mock2/sample?perPage=10",
  "body": [
    {
      "type": "table2",
      "source": "$rows",
      "onEvent": {
        "rowMouseLeave": {
          "actions": [
            {
              "actionType": "toast",
              "args": {
                "msgType": "info",
                "msg": "行索引：${event.data.index}"
              }
            }
          ]
        }
      },
      "columns": [
        {
          "name": "id",
          "label": "ID",
          "searchable": true
        },
        {
          "name": "engine",
          "label": "Rendering engine",
          "filterable": {
            "options": [
              "Internet Explorer 4.0",
              "Internet Explorer 5.0"
            ]
          }
        },
        {
          "name": "browser",
          "label": "Browser",
          "sortable": true
        },
        {
          "name": "platform",
          "label": "Platform(s)"
        },
        {
          "name": "version",
          "label": "Engine version"
        },
        {
          "name": "grade",
          "label": "CSS grade"
        }
      ]
    }
  ]
}
```

### quickSaveSubmitted

快速编辑点击 `submit` , 成功调用 `quickSaveSubmitted`之后触发

```schema: scope="body"
{
  "type": "page",
  "body": {
    "type": "page",
    "body": {
      "type": "service",
      "api": "https://3xsw4ap8wah59.cfc-execute.bj.baidubce.com/api/amis-mock/sample?perPage=5",
      "id": "service-container",
      "body": [
        {
          "type": "table2",
          "source": "$rows",
          "quickSaveApi": {
            "url": "https://3xsw4ap8wah59.cfc-execute.bj.baidubce.com/api/amis-mock/mock2/sample/bulkUpdate",
            "method": "put"
          },
          "onEvent": {
            "quickSaveSubmitted": {
              "actions": [
                {
                  "actionType": "reload",
                  "componentId": "service-container"
                }
              ]
            },
          },
          "columns": [
            {
              "title": "Engine",
              "name": "engine",
              "quickEdit": true
            },
            {
              "title": "Version",
              "name": "version"
            },
            {
              "title": "Browser",
              "name": "browser"
            },
            {
              "title": "Badge",
              "name": "badgeText"
            }
          ]
        }
      ]
    }
  }
}
```

### 列的事件表

表格的默认列定义的事件如下，即 click、mouseenter、mouseleave。如果列定义是其他组件，则事件表就是这个组件对应的事件表，例如列定义是 Switch 组件，则可以监听 [Switch 的 change 事件](./form/switch#%E4%BA%8B%E4%BB%B6%E8%A1%A8)。

| 事件名称   | 事件参数                            | 说明                                           |
| ---------- | ----------------------------------- | ---------------------------------------------- |
| click      | `[columnName]: string` 对应列名的值 | 监听表格列点击事件，表格数据点击时触发         |
| mouseenter | `[columnName]: string` 对应列名的值 | 监听表格列鼠标移入事件，表格数据鼠标移入时触发 |
| mouseleave | `[columnName]: string` 对应列名的值 | 监听表格列鼠标移出事件，表格数据鼠标移出时触发 |

可以尝试点击某行的`Rendering engine`列数据、鼠标移入某行的`Browser`列数据。

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 动作表

当前组件对外暴露以下特性动作，其他组件可以通过指定`actionType: 动作名称`、`componentId: 该组件id`来触发这些动作，动作配置可以通过`args: {动作配置项名称: xxx}`来配置具体的参数，详细请查看[事件动作](../../docs/concepts/event-action#触发其他组件的动作)。

| 动作名称  | 动作配置                                                                                                         | 说明               |
| --------- | ---------------------------------------------------------------------------------------------------------------- | ------------------ |
| select    | `selected: string` 条件表达式，表达式中可以访问变量`record:行数据`和`rowIndex:行索引`，例如: data.rowIndex === 1 | 设置表格的选中项   |
| selectAll | -                                                                                                                | 设置表格全部项选中 |
| clearAll  | -                                                                                                                | 清空表格所有选中项 |
| setValue  | `value: object`                                                                                                  | 更新列表记录       |

value 结构说明：

| 属性名        | 类型     | 默认值 | 说明     |
| ------------- | -------- | ------ | -------- |
| items 或 rows | `item[]` |        | 列表记录 |

### select

```
/* Detailed source-code truncated for AI context efficiency. */
```

### selectAll

```schema: scope="body"
[
  {
    "type": "button-toolbar",
    "className": "m-b",
    "buttons": [
      {
        "name": "trigger2",
        "id": "trigger2",
        "type": "action",
        "label": "设置表格全部项选中",
        "onEvent": {
          "click": {
            "actions": [
              {
                "actionType": "selectAll",
                "componentId": "table-select",
                "description": "点击设置指定表格全部内容选中"
              }
            ]
          }
        }
      }
    ]
  },
  {
    "type": "service",
    "api": "/api/mock2/sample?perPage=10",
    "body": [
      {
        "id": "table-select",
        "type": "table2",
        "source": "$rows",
        "selectable": true,
        "multiple": true,
        "columns": [
          {
            "name": "id",
            "label": "ID"
          },
          {
            "name": "browser",
            "label": "Browser"
          },
          {
            "name": "version",
            "label": "Version"
          }
        ]
      }
    ]
  }
]
```

### clearAll

```schema: scope="body"
[
  {
    "type": "button-toolbar",
    "className": "m-b",
    "buttons": [
      {
        "name": "trigger3",
        "id": "trigger3",
        "type": "action",
        "label": "清空表格全部选中项",
        "onEvent": {
        "click": {
            "actions": [
              {
                "actionType": "clearAll",
                "componentId": "table-select",
                "description": "点击设置指定表格全部选中项清空"
              }
            ]
          }
        }
      }
    ]
  },
  {
    "type": "service",
    "api": "/api/mock2/sample?perPage=10",
    "body": [
      {
        "id": "table-select",
        "type": "table2",
        "source": "$rows",
        "selectable": true,
        "multiple": true,
        "columns": [
          {
            "name": "id",
            "label": "ID"
          },
          {
            "name": "browser",
            "label": "Browser"
          },
          {
            "name": "version",
            "label": "Version"
          }
        ]
      }
    ]
  }
]
```

### setValue

#### 更新列表记录

```
/* Detailed source-code truncated for AI context efficiency. */
```

#### 更新指定行记录

可以通过指定`index`或者`condition`来分别更新指定索引的行记录和指定满足条件（条件表达式或者 ConditionBuilder）的行记录，另外`replace`同样生效，即可以完全替换指定行记录，也可以对指定行记录做合并。

```
/* Detailed source-code truncated for AI context efficiency. */
```

---

### Zh CN Components Tabs (`docs/zh-CN/components/tabs.md`)

---
title: Tabs 选项卡
description:
type: 0
group: ⚙ 组件
menuName: Tabs
icon:
order: 68
---

选项卡容器组件。

## 基本用法

```schema: scope="body"
{
    "type": "tabs",
    "swipeable": true,
    "tabs": [
        {
            "title": "Tab 1",
            "tab": "Content 1"
        },
        {
            "title": "Tab 2",
            "tab": "Content 2"
        }
    ]
}
```

默认想要显示多少选项卡配置多少个 `tabs` 成员即可。但是有时候你可能会想根据某个数据来动态生成。这个时候需要额外配置 `source` 属性如。

```schema
{
    "type": "page",
    "data": {
        "arr": [
            {
                "a": "收入",
                "b": 199
            },

            {
                "a": "支出",
                "b": 299
            }
        ]
    },

    "body": [
        {
            "type": "tabs",
            "source": "${arr}",
            "tabs": [
                {
                    "title": "${a}",
                    "body": {
                        "type": "tpl",
                        "tpl": "金额：${b|number}元"
                    }
                }
            ]
        }
    ]
}
```

## 拖拽排序

```schema: scope="body"
{
    "type": "tabs",
    "draggable": true,
    "tabs": [
        {
            "title": "Tab 1",
            "tab": "Content 1"
        },
        {
            "title": "Tab 2",
            "tab": "Content 2"
        },
        {
            "title": "Tab 3",
            "tab": "Content 3"
        }
    ]
}
```

## 可增加、删除

`tab` 设置的 `closable` 优先级高于整体。使用 `addBtnText` 设置新增按钮文案

```schema: scope="body"
{
    "type": "tabs",
    "closable": true,
    "addable": true,
    "addBtnText": "新增Tab",
    "tabs": [
        {
            "title": "Tab 1",
            "tab": "Content 1",
            "closable": false
        },
        {
            "title": "Tab 2",
            "tab": "Content 2"
        }
    ]
}
```

## 可编辑标签名

双击标签名，可开启编辑

```schema: scope="body"
{
    "type": "tabs",
    "editable": true,
    "tabs": [
        {
            "title": "Tab 1",
            "tab": "Content 1",
        },
        {
            "title": "Tab 2",
            "tab": "Content 2"
        },
        {
            "title": "双击编辑",
            "tab": "Content 2"
        }
    ]
}
```

## 可禁用

```schema: scope="body"
{
    "type": "tabs",
    "tabs": [
        {
            "title": "Tab 1",
            "tab": "Content 1"
        },
        {
            "title": "Tab 2",
            "tab": "Content 2",
            "disabled": true
        }
    ]
}
```

## 显示提示

```schema: scope="body"
{
    "type": "tabs",
    "showTip": true,
    "tabs": [
        {
            "title": "Tab 1",
            "tab": "Content 1"
        },
        {
            "title": "Tab 2",
            "tab": "Content 2"
        }
    ]
}
```

## 作为表单项的值

如果在表单里给 tabs 配置了 name，它可以作为一个表单提交项的值，默认情况下会取 title

```schema: scope="body"
{
    "type": "form",
    "debug": true,
    "body": [
        {
            "type": "tabs",
            "name": "tab",
            "tabs": [
                {
                    "title": "Tab 1",
                    "tab": "Content 1"
                },
                {
                    "title": "Tab 2",
                    "tab": "Content 2"
                }
            ]
        }
    ]
}
```

如果不想使用 title，可以给每个 tab 设置 value，这样就会取这个 value 作为表单项的值

```schema: scope="body"
{
    "type": "form",
    "debug": true,
    "body": [
        {
            "type": "tabs",
            "name": "tab",
            "tabs": [
                {
                    "title": "Tab 1",
                    "tab": "Content 1",
                    "value": 0
                },
                {
                    "title": "Tab 2",
                    "tab": "Content 2",
                    "value": 1
                }
            ]
        }
    ]
}
```

## 展示模式

### 简约

```schema: scope="body"
{
    "type": "tabs",
    "tabsMode": "simple",
    "tabs": [
        {
            "title": "简约(10)",
            "body": "选项卡内容1",
            "icon": "fa fa-home"
        },
        {
            "title": "选项卡2",
            "body": "选项卡内容2"
        },
        {
            "title": "选项卡3",
            "body": "选项卡内容3"
        }
    ]
}
```

### 加强

```schema: scope="body"
{
    "type": "tabs",
    "tabsMode": "strong",
    "tabs": [
        {
            "title": "选项卡1",
            "body": "选项卡内容1"
        },
        {
            "title": "选项卡2",
            "body": "选项卡内容2"
        },
        {
            "title": "选项卡3",
            "body": "选项卡内容3"
        }
    ]
}
```

### 线型

```schema: scope="body"
{
    "type": "tabs",
    "tabsMode": "line",
    "tabs": [
        {
            "title": "选项卡1",
            "body": "选项卡内容1"
        },
        {
            "title": "选项卡2",
            "body": "选项卡内容2"
        },
        {
            "title": "选项卡3",
            "body": "选项卡内容3"
        }
    ]
}
```

### 卡片

```schema: scope="body"
{
    "type": "tabs",
    "tabsMode": "card",
    "tabs": [
        {
            "title": "选项卡1",
            "body": "选项卡内容1"
        },
        {
            "title": "选项卡2",
            "body": "选项卡内容2"
        },
        {
            "title": "选项卡3",
            "body": "选项卡内容3"
        }
    ]
}
```

### 仿 Chrome

仿 Chrome tab 样式

```schema: scope="body"
{
    "type": "tabs",
    "tabsMode": "chrome",
    "tabs": [
        {
            "title": "选项卡1",
            "body": "选项卡内容1"
        },
        {
            "title": "选项卡2",
            "body": "选项卡内容2"
        },
        {
            "title": "选项卡3",
            "body": "选项卡内容3"
        }
    ]
}
```

### 水平铺满

```schema: scope="body"
{
    "type": "tabs",
    "tabsMode": "tiled",
    "tabs": [
        {
            "title": "选项卡1",
            "body": "选项卡内容1"
        },
        {
            "title": "选项卡2",
            "body": "选项卡内容2"
        },
        {
            "title": "选项卡3",
            "body": "选项卡内容3"
        },
        {
            "title": "选项卡4",
            "body": "选项卡内容4"
        }
    ]
}
```

### 选择器型

```schema: scope="body"
{
    "type": "tabs",
    "tabsMode": "radio",
    "tabs": [
        {
            "title": "选项卡1",
            "body": "选项卡内容1"
        },
        {
            "title": "选项卡2",
            "body": "选项卡内容2"
        },
        {
            "title": "选项卡3",
            "body": "选项卡内容3"
        }
    ]
}
```

### 垂直

```schema: scope="body"
{
    "type": "tabs",
    "tabsMode": "vertical",
    "tabs": [
        {
            "title": "选项卡1",
            "body": "选项卡内容1"
        },
        {
            "title": "选项卡2",
            "body": "选项卡内容2"
        },
        {
            "title": "选项卡3",
            "body": "选项卡内容3"
        }
    ]
}
```

### 侧边栏模式

使用 `sidePosition` 设置标签栏位置。

```schema: scope="body"
{
    "type": "tabs",
    "tabsMode": "sidebar",
    "sidePosition": "right",
    "tabs": [
        {
            "title": "按钮",
            "body": "选项卡内容1",
            "icon": "fa fa-square"
        },
        {
            "title": "动作",
            "body": "选项卡内容2",
            "icon": "fa fa-gavel"
        }
    ]
}
```

## 配置顶部工具栏

配置`toolbar`实现顶部工具栏。

```schema: scope="body"
{
    "type": "tabs",
    "toolbar": [
        {
            "type": "button",
            "label": "按钮",
            "size": "sm",
            "actionType": "dialog",
            "dialog": {
                "title": "弹窗标题",
                "body": "你点击了"
            }
        }
    ],
    "tabs": [
        {
            "title": "Tab 1",
            "tab": "Content 1"
        },
        {
            "title": "Tab 2",
            "tab": "Content 2"
        }
    ]
}
```

## 配置 hash

可以在单个`tab`下，配置`hash`属性，支持地址栏`#xxx`。

```schema: scope="body"
{
    "type": "tabs",
    "tabs": [
        {
            "title": "Tab 1",
            "hash": "tab1",
            "tab": "Content 1"
        },

        {
            "title": "Tab 2",
            "hash": "tab2",
            "tab": "Content 2"
        }
    ]
}
```

## 默认显示某个选项卡

主要配置`activeKey`属性来实现该效果，共有下面两种方法：

#### 配置 hash 值

支持变量，如 `"tab${id}"`

```schema: scope="body"
{
    "type": "tabs",
    "activeKey": "tab2",
    "tabs": [
        {
            "title": "Tab 1",
            "hash": "tab1",
            "tab": "Content 1"
        },

        {
            "title": "Tab 2",
            "hash": "tab2",
            "tab": "Content 2"
        }
    ]
}
```

内容来源于 source

```schema: scope="body"
{
    "type": "page",
    "data": {
        "arr": [
            {
                "a": "收入",
                "b": 199,
                "key": "a"
            },

            {
                "a": "支出",
                "b": 299,
                "key": "b"
            }
        ]
    },
    "body": [
        {
            "type": "tabs",
            "activeKey": "b",
            "source": "${arr}",
            "tabs": [
                {
                    "title": "${a}",
                    "hash": "${key}",
                    "body": {
                        "type": "tpl",
                        "tpl": "金额：${b|number}元"
                    }
                }
            ]
        }
    ]
}
```

#### 配置索引值

单个`tab`上不要配置`hash`属性，配置需要展示的`tab`索引值，`0`代表第一个。支持变量，如`"${id}"`

```schema: scope="body"
{
    "type": "tabs",
    "activeKey": 1,
    "tabs": [
        {
            "title": "Tab 1",
            "tab": "Content 1"
        },

        {
            "title": "Tab 2",
            "tab": "Content 2"
        }
    ]
}
```

### 动态设置选项卡

```schema
{
  "type": "page",
    "data": {
    "key": 2
  },
  "body": [
    {
      "type": "radios",
      "name": "key",
      "mode": "inline",
      "label": "激活的选项卡",
      "options": [
        {
          "label": "Tab 1",
          "value": 0
        },
        {
          "label": "Tab 2",
          "value": 1
        },
        {
          "label": "Tab 3",
          "value": 2
        }
      ]
    },
    {
      "type": "tabs",
      "activeKey": "${key|toInt}",
      "tabs": [
        {
          "title": "Tab 1",
          "tab": "Content 1"
        },
        {
          "title": "Tab 2",
          "tab": "Content 2"
        },
        {
          "title": "Tab 3",
          "tab": "Content 3"
        }
      ]
    }
  ]
}
```

### 初始化设置默认选项卡

> 2.7.1 以上版本

```schema
{
  "type": "page",
  "data": {
    "defaultKey": 1,
    "key": 2
  },
  "body": [
    {
      "type": "radios",
      "name": "key",
      "mode": "inline",
      "label": "激活的选项卡",
      "options": [
        {
          "label": "Tab 1",
          "value": 0
        },
        {
          "label": "Tab 2",
          "value": 1
        },
        {
          "label": "Tab 3",
          "value": 2
        }
      ]
    },
    {
      "type": "tabs",
      "activeKey": "${activeKey|toInt}",
      "defaultKey": "${defaultKey|toInt}",
      "tabs": [
        {
          "title": "Tab 1",
          "tab": "Content 1"
        },
        {
          "title": "Tab 2",
          "tab": "Content 2"
        },
        {
          "title": "Tab 3",
          "tab": "Content 3"
        }
      ]
    }
  ]
}
```

> 初始化组件时 `defaultKey` 优先级高于 `activeKey`，但 `defaultKey` 仅作用于组件初始化时，不会响应上下文数据变化。

## 图标

通过 icon 可以设置 tab 的图标，可以是 fontawesome 或 URL 地址。

```schema: scope="body"
{
    "type": "tabs",
    "tabs": [
        {
            "title": "Tab 1",
            "tab": "Content 1",
            "icon": "https://suda.cdn.bcebos.com/images%2F2021-01%2Fdiamond.svg"
        },

        {
            "title": "Tab 2",
            "tab": "Content 2"
        }
    ]
}
```

## title 自定义

> 3.2.0 及以上版本

通过配置 tabs 数组中 title 为 schema，就能自定义 title 的显示。

```schema: scope="body"
{
    "type": "tabs",
    "addBtnText": "新增Tab",
    "showTip": true,
    "tabs": [
        {
            "title": {
                "type": "container",
                "body": [
                    {
                        "type": "tpl",
                        "tpl": "这里是容器内容区"
                    },
                    {
                        "type": "icon",
                        "icon": "cloud"
                    }
                ]
            },
            "closable": true,
            "tab": "Content 1",
            "tip": "容器内容区提示"
        },
        {
            "title": "Tab 2",
            "tab": "Content 2"
        }
    ]
}
```

## 配置超出折叠

通过配置 `collapseOnExceed` 可以用来实现超出折叠，额外还能通过 `collapseBtnLabel` 配置折叠按钮的文字

```schema: scope="body"
{
    "type": "tabs",
    "tabsMode": "tiled",
    "tabs": [
        {
            "title": "Tab 1",
            "tab": "Content 1",
        },

        {
            "title": "Tab 2",
            "tab": "Content 2"
        },

        {
            "title": "Tab 3",
            "tab": "Content 3",
        },

        {
            "title": "Tab 4",
            "tab": "Content 4"
        },

        {
            "title": "Tab 5",
            "tab": "Content 5"
        }
    ],

    "collapseOnExceed": 3
}
```

## mountOnEnter

只有在点击卡片的时候才会渲染，在内容较多的时候可以提升性能，但第一次点击的时候会有卡顿。

## unmountOnExit

如果你想在切换 tab 时，自动销毁掉隐藏的 tab，请配置`"unmountOnExit": true`。

## 监听切换事件

```schema: scope="body"
{
    "type": "tabs",
    "activeKey": "tab2",
    "onSelect": "alert(key)",
    "tabs": [
      {
        "title": "Tab 1",
        "hash": "tab1",
        "tab": "Content 1"
      },
      {
        "title": "Tab 2",
        "hash": "tab2",
        "tab": "Content 2"
      }
    ]
  }
```

会传递 key 参数和 props

## 属性表

| 属性名                | 类型                                          | 默认值                              | 说明                                                                                                                                      |
| --------------------- | --------------------------------------------- | ----------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| type                  | `string`                                      | `"tabs"`                            | 指定为 Tabs 渲染器                                                                                                                        |
| defaultKey            | `string` / `number`                           |                                     | 组件初始化时激活的选项卡，hash 值或索引值，支持使用表达式 `2.7.1 以上版本`                                                                |
| activeKey             | `string` / `number`                           |                                     | 激活的选项卡，hash 值或索引值，支持使用表达式，可响应上下文数据变化                                                                       |
| className             | `string`                                      |                                     | 外层 Dom 的类名                                                                                                                           |
| linksClassName        | `string`                                      |                                     | Tabs 标题区的类名                                                                                                                         |
| contentClassName      | `string`                                      |                                     | Tabs 内容区的类名                                                                                                                         |
| tabsMode              | `string`                                      |                                     | 展示模式，取值可以是 `line`、`card`、`radio`、`vertical`、`chrome`、`simple`、`strong`、`tiled`、`sidebar`                                |
| tabs                  | `Array`                                       |                                     | tabs 内容                                                                                                                                 |
| source                | `string`                                      |                                     | tabs 关联数据，关联后可以重复生成选项卡                                                                                                   |
| toolbar               | [SchemaNode](../types/schemanode)             |                                     | tabs 中的工具栏                                                                                                                           |
| toolbarClassName      | `string`                                      |                                     | tabs 中工具栏的类名                                                                                                                       |
| tabs[x].title         | `string` \| [SchemaNode](../types/schemanode) |                                     | Tab 标题，当是 [SchemaNode](../types/schemanode) 时，该 title 不支持 editable 为 true 的双击编辑                                          |
| tabs[x].icon          | `icon`                                        |                                     | Tab 的图标                                                                                                                                |
| tabs[x].iconPosition  | `left` / `right`                              | `left`                              | Tab 的图标位置                                                                                                                            |
| tabs[x].tab           | [SchemaNode](../types/schemanode)             |                                     | 内容区                                                                                                                                    |
| tabs[x].hash          | `string`                                      |                                     | 设置以后将跟 url 的 hash 对应                                                                                                             |
| tabs[x].reload        | `boolean`                                     |                                     | 设置以后内容每次都会重新渲染，对于 crud 的重新拉取很有用                                                                                  |
| tabs[x].unmountOnExit | `boolean`                                     |                                     | 每次退出都会销毁当前 tab 栏内容                                                                                                           |
| tabs[x].className     | `string`                                      | `"bg-white b-l b-r b-b wrapper-md"` | Tab 区域样式                                                                                                                              |
| tabs[x].tip           | `string`                                      |                                     | `3.2.0及以上版本支持` Tab 提示，当开启 `showTip` 时生效，作为 Tab 在 hover 时的提示显示，可不配置，如不设置，`tabs[x].title` 作为提示显示 |
| tabs[x].closable      | `boolean`                                     | false                               | 是否支持删除，优先级高于组件的 `closable`                                                                                                 |
| tabs[x].disabled      | `boolean`                                     | false                               | 是否禁用                                                                                                                                  |
| mountOnEnter          | `boolean`                                     | true                                | 只有在点中 tab 的时候才渲染                                                                                                               |
| unmountOnExit         | `boolean`                                     | false                               | 切换 tab 的时候销毁                                                                                                                       |
| addable               | `boolean`                                     | false                               | 是否支持新增                                                                                                                              |
| addBtnText            | `string`                                      | 增加                                | 新增按钮文案                                                                                                                              |
| closable              | `boolean`                                     | false                               | 是否支持删除                                                                                                                              |
| draggable             | `boolean`                                     | false                               | 是否支持拖拽                                                                                                                              |
| showTip               | `boolean`                                     | false                               | 是否支持提示                                                                                                                              |
| showTipClassName      | `string`                                      | `'' `                               | 提示的类                                                                                                                                  |
| editable              | `boolean`                                     | false                               | 是否可编辑标签名。当 `tabs[x].title` 为 [SchemaNode](../types/schemanode) 时，双击编辑 Tab 的 title 显示空的内容                          |
| scrollable            | `boolean`                                     | true                                | 是否导航支持内容溢出滚动。（属性废弃）                                                                                                    |
| sidePosition          | `left` / `right`                              | `left`                              | `sidebar` 模式下，标签栏位置                                                                                                              |
| collapseOnExceed      | `number`                                      |                                     | 当 tabs 超出多少个时开始折叠                                                                                                              |
| collapseBtnLabel      | `string`                                      | `more`                              | 用来设置折叠按钮的文字                                                                                                                    |
| swipeable             | `boolean`                                     | false                               | 是否开启手势滑动切换（移动端生效）                                                                                                        |

## 事件表

当前组件会对外派发以下事件，可以通过`onEvent`来监听这些事件，并通过`actions`来配置执行的动作，在`actions`中可以通过`${事件参数名}`或`${event.data.[事件参数名]}`来获取事件产生的数据，详细请查看[事件动作](../../docs/concepts/event-action)。

> `[name]`表示当前组件绑定的名称，即`name`属性，如果没有配置`name`属性，则通过`value`取值。

| 事件名称 | 事件参数                             | 说明             |
| -------- | ------------------------------------ | ---------------- |
| change   | `value: number \| string` 选项卡索引 | 切换选项卡时触发 |
| delete   | `value: number \| string` 选项卡索引 | 删除选项卡时触发 |

### change

```schema: scope="body"
{
    "type": "tabs",
    "mode": "line",
    "tabs": [
    {
        "title": "选项卡1",
        "body": "选项卡内容1"
    },
    {
        "title": "选项卡2",
        "body": "选项卡内容2"
    },
    {
        "title": "选项卡3",
        "body": "选项卡内容3"
    }
    ],
    "onEvent": {
        "change": {
            "actions": [
                {
                    "actionType": "toast",
                    "args": {
                    "msgType": "info",
                    "msg": "切换至选项卡${event.data.value}"
                    }
                }
            ]
        }
    }
}
```

### delete

```schema: scope="body"
{
    "type": "tabs",
    "closable": true,
    "mode": "line",
    "tabs": [
    {
        "title": "选项卡1",
        "body": "选项卡内容1"
    },
    {
        "title": "选项卡2",
        "body": "选项卡内容2"
    },
    {
        "title": "选项卡3",
        "body": "选项卡内容3"
    }
    ],
    "onEvent": {
        "delete": {
            "actions": [
                {
                    "actionType": "toast",
                    "args": {
                        "msgType": "info",
                        "msg": "删除选项卡${event.data.value}"
                    }
                }
            ]
        }
    }
}
```

## 动作表

当前组件对外暴露以下特性动作，其他组件可以通过指定`actionType: 动作名称`、`componentId: 该组件id`来触发这些动作，动作配置可以通过`args: {动作配置项名称: xxx}`来配置具体的参数，详细请查看[事件动作](../../docs/concepts/event-action#触发其他组件的动作)。

| 动作名称        | 动作配置                                 | 说明             |
| --------------- | ---------------------------------------- | ---------------- |
| changeActiveKey | `activeKey: number \| string` 选项卡索引 | 激活指定的选项卡 |
| deleteTab       | `deleteHash: string` 选项卡 hash         | 删除指定的选项卡 |

### changeActiveKey

可以尝试点击下方按钮，实现选项卡激活。

```
/* Detailed source-code truncated for AI context efficiency. */
```

### deleteTab

可以尝试点击下方按钮，实现选项卡删除。

```
/* Detailed source-code truncated for AI context efficiency. */
```

---

### Zh CN Components Tag (`docs/zh-CN/components/tag.md`)

---
title: Tag 标签
description:
type: 0
group: ⚙ 组件
menuName: Tabs
icon:
---

用于标记和选择的标签

## 基本用法

```schema
{
    type: "page",
    body: [
        {
            "type": "tag",
            "label": "普通的标签",
            "displayMode": "rounded",
            "color": "inactive"
        },
        {
            "type": "tag",
            "label": "普通标签",
            "color": "processing"
        },
        {
            "type": "tag",
            "label": "这是一个很长长长长长长长长长长长长长的标签",
            "color": "success"
        },
        {
            "type": "tag",
            "label": "这是一个很长长长长长长长长长长长长长的标签",
            "closable": true
        },
        {
            type: 'tag',
            label: '关闭了！',
            closable: true,
            onEvent: {
                close: {
                actions: [
                    {
                        actionType: 'toast',
                        args: {
                            msg: '${event.data.label}'
                        }
                    }
                ]
                }
            }
        }
    ]
}
```

## 不同的模式

```schema
{
    "type": "page",
    "body": [
        {
            "type": "tag",
            "label": "面性标签",
            "displayMode": "normal",
            "color": "active"
        },
        {
            "type": "tag",
            "label": "线性标签",
            "displayMode": "rounded",
            "color": "inactive"
        },
        {
            "type": "tag",
            "label": "状态标签",
            "displayMode": "status",
            "color": "active",
            "closable": true
        },
        {
            "type": "tag",
            "label": "#4096ff",
            "displayMode": "rounded",
            "color": "#4096ff"
        },
        {
            "type": "tag",
            "label": "#f70e47",
            "displayMode": "rounded",
            "color": "#f70e47"
        }
    ]
}
```

## 标签颜色

标签有几种预设的色彩样式，可以通过设置 color 属性为 active、inactive、error、success、iprocessing、warning 用作不同场景使用。如果预设值不能满足需求，可以设置为具体的色值

```schema
{
    "type": "page",
    "body": [
        {
            "type": "tag",
            "label": "active",
            "displayMode": "normal",
            "color": "active"
        },
        {
            "type": "tag",
            "label": "inactive",
            "displayMode": "normal",
            "color": "inactive"
        },
        {
            "type": "tag",
            "label": "error",
            "displayMode": "normal",
            "color": "error"
        },
        {
            "type": "tag",
            "label": "success",
            "displayMode": "normal",
            "color": "success"
        },
        {
            "type": "tag",
            "label": "processing",
            "displayMode": "normal",
            "color": "processing"
        },
        {
            "type": "tag",
            "label": "warning",
            "displayMode": "normal",
            "color": "warning"
        }
    ]
}
```

## 自定义样式

可以通过 style 来控制背景、边框及文字颜色。如下

```schema
{
    "type": "page",
    "body": [
        {
            "type": "tag",
            "label": "面性标签",
            "displayMode": "normal",
            "color": "active"
        },
        {
            "type": "tag",
            "label": "线性标签",
            "displayMode": "rounded",
            "color": "inactive"
        },
        {
            "type": "tag",
            "label": "自定义样式1",
            "displayMode": "normal",
            "style": {
                "backgroundColor": "#fff",
                "border": "1px solid #ccc",
                "color": "#666",
            }
        },
        {
            "type": "tag",
            "label": "自定义样式2",
            "displayMode": "rounded",
            "style": {
                "backgroundColor": "#2468f2",
                "borderColor": "#2468f2",
                "color": "#fff",
            }
        },
    ]
}
```

## 属性表

| 属性名      | 类型                                                                                      | 默认值     | 说明                                       |
| ----------- | ----------------------------------------------------------------------------------------- | ---------- | ------------------------------------------ |
| displayMode | `'normal' \| 'rounded' \| 'status'`                                                       | `normal`   | 展现模式                                   |
| color       | `'active' \| 'inactive' \| 'error' \| 'success' \| 'processing' \| 'warning' \| 具体色值` |            | 颜色主题，提供默认主题，并支持自定义颜色值 |
| label       | `string`                                                                                  | `-`        | 标签内容                                   |
| icon        | `SchemaIcon`                                                                              | `dot 图标` | status 模式下的前置图标                    |
| className   | `string`                                                                                  |            | 自定义 CSS 样式类名                        |
| style       | `object`                                                                                  | {}         | 自定义样式（行内样式），优先级最高         |
| closable    | `boolean`                                                                                 | `false`    | 是否展示关闭按钮                           |

## 事件表

> 2.6.1 及以上版本

当前组件会对外派发以下事件，可以通过`onEvent`来监听这些事件，并通过`actions`来配置执行的动作，在`actions`中可以通过`${事件参数名}`或`${event.data.[事件参数名]}`来获取事件产生的数据，详细查看[事件动作](../../docs/concepts/event-action)。

| 事件名称   | 事件参数                     | 说明             |
| ---------- | ---------------------------- | ---------------- |
| click      | `label: string` 鼠标事件对象 | `点击`时触发     |
| mouseenter | `label: string` 鼠标事件对象 | `鼠标移入`时触发 |
| mouseleave | `label: string` 鼠标事件对象 | `鼠标移出`时触发 |
| close      | `label: string` 鼠标事件对象 | `关闭`时触发     |

### click

鼠标点击。可以尝试通过`${event.context.nativeEvent}`获取鼠标事件对象。

```schema: scope="body"
{
    "type": "tag",
    "label": "success",
    "displayMode": "normal",
    "color": "success",
    "onEvent": {
        "click": {
            "actions": [
            {
                "actionType": "toast",
                "args": {
                "msgType": "info",
                "msg": "${event.context.nativeEvent.type} ${event.data.label}"
                }
            }
            ]
        }
    }
}
```

### mouseenter

鼠标移入。可以尝试通过`${event.context.nativeEvent}`获取鼠标事件对象。

```schema: scope="body"
{
   "type": "tag",
    "label": "success",
    "displayMode": "normal",
    "color": "success",
    "onEvent": {
        "mouseenter": {
        "actions": [
            {
            "actionType": "toast",
            "args": {
                "msgType": "info",
                "msg": "${event.context.nativeEvent.type} ${event.data.label}"
            }
            }
        ]
        }
    }
}
```

### mouseleave

鼠标移出。可以尝试通过`${event.context.nativeEvent}`获取鼠标事件对象。

```schema: scope="body"
{
   "type": "tag",
    "label": "success",
    "displayMode": "normal",
    "color": "success",
    "onEvent": {
        "mouseleave": {
        "actions": [
            {
            "actionType": "toast",
            "args": {
                "msgType": "info",
                "msg": "${event.context.nativeEvent.type} ${event.data.label}"
            }
            }
        ]
        }
    }
}
```

### close

鼠标点击关闭标签。可以尝试通过`${event.context.nativeEvent}`获取鼠标事件对象。

```schema: scope="body"
{
   "type": "tag",
    "label": "success",
    "displayMode": "normal",
    "color": "success",
    "closable": true,
    "onEvent": {
        "close": {
        "actions": [
            {
            "actionType": "toast",
            "args": {
                "msgType": "info",
                "msg": "close ${event.context.nativeEvent.label}"
            }
            }
        ]
        }
    }
}
```

---

### Zh CN Components Tasks (`docs/zh-CN/components/tasks.md`)

---
title: Tasks 任务操作集合
description:
type: 0
group: ⚙ 组件
menuName: Tasks
icon:
order: 69
---

任务操作集合，类似于 orp 上线。

## 基本用法

```schema: scope="body"
{
    "type": "tasks",
    "name": "tasks",
    "items": [
        {
            "label": "hive 任务",
            "key": "hive",
            "status": 4,
            "remark": "查看详情<a target=\"_blank\" href=\"http://www.baidu.com\">日志</a>。"
        },
        {
            "label": "小流量",
            "key": "partial",
            "status": 4
        },
         {
             "label": "全量",
             "key": "full",
             "status": 4
         }
    ]
}
```

## 属性表

| 属性名            | 类型                        | 默认值                                                                                              | 说明                                                                                                                                      |
| ----------------- | --------------------------- | --------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| type              | `string`                    | `"tasks"`                                                                                           | 指定为 Tasks 渲染器                                                                                                                       |
| className         | `string`                    |                                                                                                     | 外层 Dom 的类名                                                                                                                           |
| tableClassName    | `string`                    |                                                                                                     | table Dom 的类名                                                                                                                          |
| items             | `Array`                     |                                                                                                     | 任务列表                                                                                                                                  |
| items[x].label    | `string`                    |                                                                                                     | 任务名称                                                                                                                                  |
| items[x].key      | `string`                    |                                                                                                     | 任务键值，请唯一区分                                                                                                                      |
| items[x].remark   | `string`                    |                                                                                                     | 当前任务状态，支持 html                                                                                                                   |
| items[x].status   | `string`                    |                                                                                                     | 任务状态： 0: 初始状态，不可操作。1: 就绪，可操作状态。2: 进行中，还没有结束。3：有错误，不可重试。4: 已正常结束。5：有错误，且可以重试。 |
| checkApi          | [API](../../docs/types/api) |                                                                                                     | 返回任务列表，返回的数据请参考 items。                                                                                                    |
| submitApi         | [API](../../docs/types/api) |                                                                                                     | 提交任务使用的 API                                                                                                                        |
| reSubmitApi       | [API](../../docs/types/api) |                                                                                                     | 如果任务失败，且可以重试，提交的时候会使用此 API                                                                                          |
| interval          | `number`                    | `3000`                                                                                              | 当有任务进行中，会每隔一段时间再次检测，而时间间隔就是通过此项配置，默认 3s。                                                             |
| taskNameLabel     | `string`                    | 任务名称                                                                                            | 任务名称列说明                                                                                                                            |
| operationLabel    | `string`                    | 操作                                                                                                | 操作列说明                                                                                                                                |
| statusLabel       | `string`                    | 状态                                                                                                | 状态列说明                                                                                                                                |
| remarkLabel       | `string`                    | 备注                                                                                                | 备注列说明                                                                                                                                |
| btnText           | `string`                    | 上线                                                                                                | 操作按钮文字                                                                                                                              |
| retryBtnText      | `string`                    | 重试                                                                                                | 重试操作按钮文字                                                                                                                          |
| btnClassName      | `string`                    | `btn-sm btn-default`                                                                                | 配置容器按钮 className                                                                                                                    |
| retryBtnClassName | `string`                    | `btn-sm btn-danger`                                                                                 | 配置容器重试按钮 className                                                                                                                |
| statusLabelMap    | `array`                     | `["label-warning", "label-info", "label-success", "label-danger", "label-default", "label-danger"]` | 状态显示对应的类名配置                                                                                                                    |
| statusTextMap     | `array`                     | `["未开始", "就绪", "进行中", "出错", "已完成", "出错"]`                                            | 状态显示对应的文字显示配置                                                                                                                |

```schema: scope="body"
[
{
    "type": "tasks",
    "name": "tasks",
    "checkApi": "/api/mock2/task"
},

"为了演示，目前获取的状态都是随机出现的。"]
```

---

### Zh CN Components Timeline (`docs/zh-CN/components/timeline.md`)

---
title: Timeline 时间轴
description:
type: 0
group: ⚙ 组件
menuName: Timeline
icon:
order: 73
---

时间轴组件

## 基本用法

```schema
{
  "type": "page",
  "body": [
    {
      type: 'timeline',
      direction: 'vertical',
      items: [
        {
          time: '2019-02-07',
          title: '图片集说明',
          detail:
            '图片集展示，不支持配置初始化接口初始化数据域，所以需要搭配类似像Service、Form或CRUD这样的，具有配置接口初始化数据域功能的组件，或者手动进行数据域初始化，然后通过source属性，获取数据链中的数据，完成数据展示。'
        },
        {
          time: '2019-02-08',
          title: '卡片组说明',
          detail:
            '卡片展示，不支持配置初始化接口初始化数据域，所以需要搭配类似像Service这样的，具有配置接口初始化数据域功能的组件，或者手动进行数据域初始化，然后通过source属性，获取数据链中的数据，完成数据展示。'
        },
        {
          time: '2019-02-09',
          title: '宫格导航说明',
          detail:
            '宫格菜单导航，不支持配置初始化接口初始化数据域，所以需要搭配类似像Service、Form或CRUD这样的，具有配置接口初始化数据域功能的组件，或者手动进行数据域初始化，然后通过source属性，获取数据链中的数据，完成菜单展示。'
        },
        {
          time: '2019-02-10',
          title: '表格展现说明',
          detail:
            '通过表格的方式来展现数据，和 table 的不同之处：数据源要求不同：table 的数据源需要是多行的数据，最典型的就是来自某个数据库的表，table view 的数据源可以来自各种固定的数据，比如单元格的某一列是来自某个变量。功能不同：table 只能用来做数据表的展现，table view 除了展现复杂的报表，还能用来进行布局。合并单元格方式不同：table 的合并单元格需要依赖数据，table view 的合并单元格是手动指定的，因此可以支持不规则的数据格式。'
        }
      ]
    }
  ]
}
```

## 时间轴节点颜色设置

支持设置自定义节点颜色，或者使用内置的颜色值。内置颜色值有：`success`, `warning`, `danger`, `info`。

```schema
{
  "type": "page",
  "body": [
    {
      "type": "timeline",
      "items": [
        {
          "time": "2019-02-07",
          "title": "节点数据",
          "color": "#ffb200",
          "backgroundColor": "#eeb739"
        },
        {
          "time": "2019-02-08",
          "title": "节点数据",
          "color": "#4F86F4",
        },
        {
          "time": "2019-02-09",
          "title": "节点数据",
          "color": "success",
        },
        {
          "time": "2019-02-09",
          "title": "节点数据",
          "color": "warning",
        }
      ]
    }
  ]
}
```

## 时间轴节点的位置、隐藏、大小配置

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 时间轴节点图标设置

```schema
{
  "type": "page",
  "data": {
    "image": "https://suda.cdn.bcebos.com/images%2F2021-01%2Fsearch.svg"
  },
  "body": [
    {
      "type": "timeline",
      "items": [
        {
          "time": "2019-02-07",
          "title": "节点数据error",
          "detail": "error",
          "icon": "fail"
        },
        {
          "time": "2019-02-08",
          "title": "节点数据success",
          "detail": "success",
          "icon": "success"
        },
        {
          "time": "2019-02-09",
          "title": "节点数据(自定义图片)",
          "detail": "warning",
          "icon": "${image}",
        }
      ]
    },{
      "type": "timeline",
      "direction": "horizontal",
      "items": [
        {
          "time": "2019-02-07",
          "title": "节点数据error",
          "detail": "error",
          "icon": "fail"
        },
        {
          "time": "2019-02-08",
          "title": "节点数据success",
          "detail": "success",
          "icon": "success"
        },
        {
          "time": "2019-02-09",
          "title": "节点数据(自定义图片)",
          "detail": "warning",
          "icon": "${image}",
        }
      ]
    }
  ]
}
```

## 时间轴分段颜色设置

```schema
{
  "type": "page",
  "body": [
    {
      "type": "timeline",
      "items": [
        {
          "time": "2019-02-07",
          "title": "节点数据error",
          "detail": "error",
          "icon": "fail",
          "lineColor": "#2e86d3",
        },
        {
          "time": "2019-02-08",
          "title": "节点数据success",
          "detail": "success",
          "icon": "success",
          "lineColor": "#2ee414",
        },
        {
          "time": "2019-02-09",
          "title": "节点数据(自定义图片)",
          "detail": "warning",
          "lineColor": "#e45c14",
          "icon": "${image}"
        }
      ]
    }
  ]
}
```

## 节点标题自定义

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 设置节点数据倒序

```schema
{
  "type": "page",
  "body": [
    {
      "type": "timeline",
      direction: "vertical",
      reverse: true,
      "items": [
        {
          "time": "2019-02-07",
          "title": "节点数据",
        },
        {
          "time": "2019-02-08",
          "title": "节点数据",
        },
        {
          "time": "2019-02-09",
          "title": "节点数据",
        },
        {
          "time": "2019-02-10",
          "title": "节点数据",
        },
      ]
    }
  ]
}
```

## 设置时间轴方向

```schema
{
  "type": "page",
  "body": [
    {
      "type": "timeline",
      direction: "horizontal",
      "items": [
        {
          "time": "2019-02-07",
          "title": "节点数据",
          "dotSize": "xl"
        },
        {
          "time": "2019-02-08",
          "title": "节点数据",
        },
        {
          "time": "2019-02-09",
          "title": "节点数据",
        },
        {
          "time": "2019-02-10",
          "title": "节点数据",
        },
      ]
    }
  ]
}
```

## 设置文字相对时间轴方向

### 纵向

#### 文字位于时间轴左侧

```schema
{
  "type": "page",
  "body": [
    {
      "type": "timeline",
      "mode": "left",
      "items": [
        {
          "time": "2019-02-07",
          "title": "节点数据",
          "detail": "error",
        },
        {
          "time": "2019-02-08",
          "title": "节点数据",
          "detail": "success",
        }
      ]
    },
  ]
}
```

#### 文字交替位于时间轴两侧

```schema
{
  "type": "page",
  "body": [
    {
      "type": "timeline",
      "mode": "alternate",
      "items": [
        {
          "time": "2019-02-07",
          "title": "节点数据",
          "detail": "error",
        },
        {
          "time": "2019-02-08",
          "title": "节点数据",
          "detail": "success",
        }
      ]
    }
  ]
}
```

#### 文字位于时间轴右侧

```schema
{
  "type": "page",
  "body": [
    {
      "type": "timeline",
      "mode": "right",
      "items": [
        {
          "time": "2019-02-07",
          "title": "节点数据",
          "detail": "error",
        },
        {
          "time": "2019-02-08",
          "title": "节点数据",
          "detail": "success",
        }
      ]
    },
  ]
}
```

### 横向

#### 时间标题位于时间轴上侧

```schema
{
  "type": "page",
  "body": [
    {
      "type": "timeline",
      "mode": "top",
      "direction": "horizontal",
      "items": [
        {
          "time": "2019-02-07",
          "title": "节点数据",
          "detail": "error",
        },
        {
          "time": "2019-02-08",
          "title": "节点数据",
          "detail": "success",
        }
      ]
    },
  ]
}
```

#### 时间标题位于时间轴下侧

```schema
{
  "type": "page",
  "body": [
    {
      "type": "timeline",
      "mode": "bottom",
      "direction": "horizontal",
      "items": [
        {
          "time": "2019-02-07",
          "title": "节点数据",
          "detail": "error",
        },
        {
          "time": "2019-02-08",
          "title": "节点数据",
          "detail": "success",
        }
      ]
    },
  ]
}
```

#### 时间标题和内容交替位于时间轴两侧

```schema
{
  "type": "page",
  "body": [
    {
      "type": "timeline",
      "mode": "alternate",
      "direction": "horizontal",
      "items": [
        {
          "time": "2019-02-07",
          "title": "节点数据",
          "detail": "error",
        },
        {
          "time": "2019-02-08",
          "title": "节点数据",
          "detail": "success",
        }
      ]
    },
  ]
}
```

## 时间轴内容支持卡片展示

```schema
{
  "type": "page",
  "body": [
    {
      type: 'timeline',
      mode: 'alternate',
      direction: 'horizontal',
      items: [
        {
          cardSchema: {
            type: 'card',
            href: 'https://github.com/baidu/amis',
            header: {
              title: '标题',
              subTitle: '副标题',
              description: '这是一段描述',
              avatarText: 'AMIS'
            },
            body: '这里是内容'
          }
        },
        {
          time: '2019-02-08',
          cardSchema: {
            type: 'card',
            href: 'https://github.com/baidu/amis',
            header: {
              title: '标题',
              subTitle: '副标题',
              description: '这是一段描述',
              avatarText: 'AMIS'
            },
            body: '这里是内容'
          }
        },
        {
          time: '2019-02-09',
          title: '表格展现说明',
          detail:
            '通过表格的方式来展现数据，和 table 的不同之处：数据源要求不同：table 的数据源需要是多行的数据，最典型的就是来自某个数据库的表，table view 的数据源可以来自各种固定的数据，比如单元格的某一列是来自某个变量。功能不同：table 只能用来做数据表的展现，table view 除了展现复杂的报表，还能用来进行布局。合并单元格方式不同：table 的合并单元格需要依赖数据，table view 的合并单元格是手动指定的，因此可以支持不规则的数据格式。'
        }
      ]
    }
  ]
}
```

如果当前所有节点均需要以卡片形式展示，可以通过 timeline 节点增加 `cardSchema`以统一卡片渲染模板。在这种情况下，每个 `timelineItem`内的数据都可以作为数据引用，在 `cardSchema` 中引用展示。

```schema
{
  type: 'page',
  data: {
    content: '这里是卡片主体内容，在所有的卡片都会展示'
  },
  body: {
    type: 'timeline',
    mode: 'alternate',
    direction: 'horizontal',
    cardSchema: {
      type: 'card',
      href: 'https://github.com/baidu/amis',
      header: {
        title: '${title}',
        subTitle: '${time}',
        description: '${detail}'
      },
      body: '${content}'
    },
    items: [
      {
        cardSchema: {
          type: 'card',
          href: 'https://github.com/baidu/amis',
          header: {
            title: '标题',
            subTitle: '副标题',
            description: '这是一段描述',
            avatarText: 'AMIS'
          },
          body: '这里是内容'
        }
      },
      {
        time: '2019-02-08',
        title: '卡片组说明',
        detail:
          'Content'
      },
      {
        time: '2019-02-09',
        title: '表格展现说明',
        detail:
          'Content'
      }
    ]
  }
}
```

## 动态数据

### 远程数据

```schema
{
  "type": "page",
  "body": [
    {
      "type": "timeline",
      "source": {
        "method": "get",
        "url": "/api/mock2/timeline/timelineItems"
      }


    }
  ]
}
```

"source": "/api/mock2/timeline/timelineItems",

远程拉取接口时，返回的数据结构除了需要满足 amis 接口要求的基本数据结构 以外，必须用"items"作为时间轴数据的 key 值，如下：

```json
{
  "status": 0,
  "msg": "",
  "data": {
    "items": [
      {
        "time": "2019-02-07",
        "title": "数据开发",
        "detail": "2019-02-07detail",
        "color": "#ffb200",
        "icon": "close"
      },
      {"time": "2019-02-08", "title": "管理中心", "detail": "2019-02-08detail"},
      {
        "time": "2019-02-09",
        "title": "SQL语句",
        "detail": "2019-02-09detail",
        "color": "warning"
      },
      {
        "time": "2019-02-10",
        "title": "一键部署",
        "detail": "2019-02-10detail",
        "icon": "compress-alt"
      },
      {"time": "2019-02-10", "title": "一键部署", "detail": "2019-02-11detail"},
      {
        "time": "2019-02-10",
        "title": "一键部署",
        "detail": "2019-02-12detail",
        "icon": "close"
      },
      {"time": "2019-02-10", "title": "一键部署", "detail": "2019-02-13detail"}
    ]
  }
}
```

### 数据域变量配置

> 3.4.0 及以上版本

```schema
{
  "type": "page",
  "data": {
    "items": [
      {
        "title": "First",
        "time": "this is subTitle",
        "detail": "this is description"
      },
      {
        "title": "Second"
      },
      {
        "title": "Last"
      }
    ]
  },
  "body": [
    {
      "type": "timeline",
      "source": "${items}"
    }
  ]
}
```

```schema
{
  "type": "page",
  "data": {
    "items":
      {
        "First": "this is subTitle",
        "detail": "this is description",
        "title": "Second"
      }
  }
  ,
  "body": [
    {
      "type": "timeline",
      "source": "${items}"
    }
  ]
}
```

## 属性表

| 属性名          | 类型                                                                              | 默认值         | 说明                                                                                                                                                                                                                                                                             |
| --------------- | --------------------------------------------------------------------------------- | -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| type            | `string`                                                                          |                | `"timeline"` 指定为 时间轴 渲染器                                                                                                                                                                                                                                                |
| items           | Array<[timelineItem](#timeline.item)>                                             | []             | 配置节点数据                                                                                                                                                                                                                                                                     |
| source          | [API](../../../docs/types/api) 或 [数据映射](../../../docs/concepts/data-mapping) |                | 数据源，可通过数据映射获取当前数据域变量、或者配置 API 对象                                                                                                                                                                                                                      |
| mode            | `left` \| `right` \| `alternate` \| `top` \| `bottom`                             | ` right``top ` | 可选。支持时间在左/上展示，标题和内容在右/下展示，以及时间和内容交错方向展示。left / right 在 direction 为 vertical 时生效，top / bottom 在 direction 为 vertical 时生效。(v6.11.0 以前版本只有 vertical 支持，horizontal 不支持设置模式)                                        |
| direction       | `vertical` \| `horizontal`                                                        | `vertical`     | 时间轴方向                                                                                                                                                                                                                                                                       |
| reverse         | `boolean`                                                                         | `false`        | 根据时间倒序显示                                                                                                                                                                                                                                                                 |
| iconClassName   | `string`                                                                          |                | 统一配置的节点图标 CSS 类（3.4.0 版本支持）名                                                                                                                                                                                                                                    |
| timeClassName   | `string`                                                                          |                | 统一配置的节点时间 CSS 类（3.4.0 版本支持）名                                                                                                                                                                                                                                    |
| titleClassName  | `string`                                                                          |                | 统一配置的节点标题 CSS 类（3.4.0 版本支持）名                                                                                                                                                                                                                                    |
| detailClassName | `string`                                                                          |                | 统一配置的节点详情 CSS 类（3.4.0 版本支持）名                                                                                                                                                                                                                                    |
| cardSchema      | `string`                                                                          |                | 统一配置子节点渲染卡片模板。配置后  itemTitleSchema、titleClassName、detailClassName 将不生效。配置后 timeline item 中的数据都将可以在 cardSchema 中通过数据方式引用。如果子节点也配置了 cardSchema，子节点的 cardSchema 优先级高于 timeline 的 cardSchema。（v6.12.1 之后支持） |

### timeline.item

| 属性名              | 类型                                                    | 默认值         | 说明                                                                                                                                                              |
| ------------------- | ------------------------------------------------------- | -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| time                | `string `                                               |                | 节点时间                                                                                                                                                          |
| title               | `string` \| [SchemaNode](../../docs/types/schemanode)   |                | 节点标题                                                                                                                                                          |
| detail              | `string`                                                |                | 节点详细描述（折叠）                                                                                                                                              |
| detailCollapsedText | `string`                                                | `展开`         | 详细内容折叠时按钮文案                                                                                                                                            |
| detailExpandedText  | `string`                                                | `折叠`         | 详细内容展开时按钮文案                                                                                                                                            |
| color               | `string \| level样式（info、success、warning、danger）` | `#DADBDD`      | 时间轴节点颜色                                                                                                                                                    |
| backgroundColor     | `string`                                                | `#070c14`      | 时间点圆圈后部阴影颜色。（v6.11.1 版本支持）                                                                                                                      |
| icon                | `string`                                                |                | icon 名，支持 fontawesome v4 或使用 url（优先级高于 color）                                                                                                       |
| iconClassName       | `string`                                                |                | 节点图标的 CSS 类名（优先级高于统一配置的 iconClassName ，（3.4.0 版本支持））                                                                                    |
| timeClassName       | `string`                                                |                | 节点时间的 CSS 类名（优先级高于统一配置的 timeClassName，（3.4.0 版本支持））                                                                                     |
| titleClassName      | `string`                                                |                | 节点标题的 CSS 类名（优先级高于统一配置的 titleClassName，（3.4.0 版本支持））                                                                                    |
| detailClassName     | `string`                                                |                | 节点详情的 CSS 类名（优先级高于统一配置的 detailClassName，（3.4.0 版本支持））                                                                                   |
| dotSize             | `sm` \| `md` \| `lg` \| `xl`                            | `md`           | 当前节点大小。（v6.11.1 版本支持                                                                                                                                  |
| lineColor           | `string`                                                | `#e6e6e8`      | 连线颜色。（v6.11.1 版本支持）                                                                                                                                    |
| hideDot             | `boolean`                                               | `false`        | 是否隐藏当前节点的圆圈。（v6.11.1 版本支持）                                                                                                                      |
| align               | `left` \| `center` \| `right` \| `top` \| `bottom`      | `center` `top` | 圆点的对齐方式。水平排列时，可选值为 left center right，默认为 center;垂直排列时，可选值为 top bottom center，默认为 top。（v6.11.1 版本支持）                    |
| cardSchema          | `CardSchema`                                            |                | 卡片展示配置，如果传入则以卡片形式展示，传入对象转为卡片展示，传入的 time、title、detail 及相关属性将被忽略，只有连线配置和节点圆圈配置生效。（v6.11.1 版本支持） |

---

### Zh CN Components Toast (`docs/zh-CN/components/toast.md`)

---
title: Toast 轻提示
description:
type: 0
group: ⚙ 组件
menuName: Toast
icon:
order: 70
---

## 基本用法

```schema: scope="body"
[
  {
    "label": "提示",
    "type": "button",
    "actionType": "toast",
    "toast": {
      "items": [
        {body: '轻提示内容'}
      ]
    }
  },
  {
    "label": "提示2",
    "type": "button",
    "actionType": "toast",
    "toast": {
      "items": [
        {body: '轻提示内容2'}
      ]
    }
  },
]
```

## 设置位置

```schema: scope="body"
{
    "label": "提示",
    "type": "button",
    "actionType": "toast",
    "toast": {
      "position": "bottom-center",
      "items": [
        {body: '轻提示内容2'}
      ]
    }
}
```

## 不展示关闭按钮

```schema: scope="body"
{
    "label": "提示",
    "type": "button",
    "actionType": "toast",
    "toast": {
      "closeButton": false,
      "items": [
        {body: '轻提示内容'}
      ]
    }
}
```

## 关闭图标展示

```schema: scope="body"
{
    "label": "提示",
    "type": "button",
    "actionType": "toast",
    "toast": {
      "showIcon": false,
      "items": [
        {body: '轻提示内容'}
      ]
    }
}
```

## 持续时间设置

```schema: scope="body"
{
    "label": "提示",
    "type": "button",
    "actionType": "toast",
    "toast": {
      "timeout": 1000,
      "items": [
        {body: '轻提示内容'}
      ]
    }
}
```

## 带标题的提示

```schema: scope="body"
{
    "label": "提示",
    "type": "button",
    "actionType": "toast",
    "toast": {
      "items": [
        {title: '标题', body: '轻提示内容'}
      ]
    }
}
```

## 提示单独设置不同的类型

```schema: scope="body"
{
    "label": "提示",
    "type": "button",
    "actionType": "toast",
    "toast": {
      "items": [
        {body: '普通消息提示', level: 'info'},
        {body: '成功消息提示', level: 'success'},
        {body: '错误消息提示', level: 'error'},
        {body: '警告消息提示', level: 'warning'}
      ]
    }
}
```

## 提示单独设置不同的位置

```schema: scope="body"
{
    "label": "提示",
    "type": "button",
    "actionType": "toast",
    "toast": {
      "items": [
        {body: '左上方提示', position: 'top-left'},
        {body: '上方提示', position: 'top-center'},
        {body: '右上方提示', position: 'top-right'},
        {body: '中间提示', position: 'center'},
        {body: '左下方提示', position: 'bottom-left'},
        {body: '下方提示', position: 'bottom-center'},
        {body: '右上下方提示', position: 'bottom-right'}
      ]
    }
}
```

## 提示单独设置是否展示关闭按钮

```schema: scope="body"
{
    "label": "提示",
    "type": "button",
    "actionType": "toast",
    "toast": {
      "items": [
        {body: '展示关闭按钮', closeButton: true},
        {body: '不展示关闭按钮', closeButton: false}
      ]
    }
}
```

## 提示单独设置不同的持续时间

```schema: scope="body"
{
    "label": "提示",
    "type": "button",
    "actionType": "toast",
    "toast": {
      "items": [
        {body: '持续1秒', timeout: 1000},
        {body: '持续3秒', timeout: 3000}
      ]
    }
}
```

## 渲染 html

```schema: scope="body"
{
    "label": "提示",
    "type": "button",
    "actionType": "toast",
    "toast": {
      "items": [
        {body: '<strong>Hello</strong> <span>world</span>'},
      ]
    }
}
```

## 属性表

| 属性名      | 类型               | 默认值                                  | 说明                                                                                                              |
| ----------- | ------------------ | --------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| actionType  | `string`           | `"toast"`                               | 指定为 toast 轻提示组件                                                                                           |
| items       | `Array<ToastItem>` | `[]`                                    | 轻提示内容                                                                                                        |
| position    | `string`           | `top-center（移动端为center）`          | 提示显示位置，可用'top-right'、'top-center'、'top-left'、'bottom-center'、'bottom-left'、'bottom-right'、'center' |
| closeButton | `boolean`          | `false`                                 | 是否展示关闭按钮，移动端不展示                                                                                    |
| showIcon    | `boolean`          | `true`                                  | 是否展示图标                                                                                                      |
| timeout     | `number`           | `5000（error类型为6000，移动端为3000）` | 持续时间                                                                                                          |

## ToastItem 属性表

| 属性名      | 类型                   | 默认值                                  | 说明                                                                                                              |
| ----------- | ---------------------- | --------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| title       | `string \| SchemaNode` |                                         | 标题                                                                                                              |
| body        | `string \| SchemaNode` |                                         | 内容                                                                                                              |
| level       | `string`               | `info`                                  | 展示图标，可选'info'、'success'、'error'、'warning'                                                               |
| position    | `string`               | `top-center（移动端为center）`          | 提示显示位置，可用'top-right'、'top-center'、'top-left'、'bottom-center'、'bottom-left'、'bottom-right'、'center' |
| closeButton | `boolean`              | `false`                                 | 是否展示关闭按钮                                                                                                  |
| showIcon    | `boolean`              | `true`                                  | 是否展示图标                                                                                                      |
| timeout     | `number`               | `5000（error类型为6000，移动端为3000）` | 持续时间                                                                                                          |
| allowHtml   | `boolean`              | `true`                                  | 是否会被当作 HTML 片段处理                                                                                        |

---

### Zh CN Components Tooltip Wrapper (`docs/zh-CN/components/tooltip-wrapper.md`)

---
title: TooltipWrapper 文字提示容器
description:
type: 0
group: ⚙ 功能
menuName: TooltipWrapper
icon:
order: 59
---

## 基本配置

当用户鼠标悬停或者点击元素时，显示文字提示浮层，`title`可以为浮层添加标题。

```schema: scope="body"
[
  {
    "type": "flex",
    "justify": "space-around",
    "alignItems": "center",
    "direction": "row",
    "style": {
      "width": 350,
      "height": 30
    },
    "items": [
      {
        "type": "tooltip-wrapper",
        "content": "提示文字",
        "body": "hover 激活文字提示",
        "className": "mb-1"
      },
      {
        "type": "tooltip-wrapper",
        "title": "标题",
        "content": "提示文字",
        "trigger": "click",
        "body": "click 激活文字提示",
        "className": "mb-1"
      }
    ]
  }
]
```

`body`支持传入多个子元素：

```schema: scope="body"
[
  {
    "type": "tooltip-wrapper",
    "content": "删除提示",
    "inline": true,
    "body": [
      {
        "type": "tpl",
        "tpl": "删除"
      },
      {
        "className": "ml-1",
        "type": "icon",
        "icon": "trash"
      }
    ]
  }
]
```

## 提示位置

提供四种不同方向的展示方式：`'top' | 'left' | 'right' | 'bottom'`。

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 位置偏移

组件提供了关于相对提示位置的垂直、水平位置上的偏移，默认[0, 0]。

```schema: scope="body"
[
  {
    "type": "tooltip-wrapper",
    "title": "标题",
    "content": "文案提示位置偏移 [10, -20]",
    "offset": [10, -20],
    "inline": true,
    "className": "mr-2",
    "body": [
      {
        "type": "tpl",
        "tpl": "向右偏移10px向上偏移20px"
      }
    ]
  }
]

```

## 展示箭头

`showArrow` 为 `false` 不展示箭头。

```schema: scope="body"
[
  {
    "type": "tooltip-wrapper",
    "title": "标题",
    "content": "提示内容",
    "showArrow": false,
    "inline": true,
    "className": "mr-2",
    "body": [
      {
        "type": "tpl",
        "tpl": "没有箭头"
      }
    ]
  }
]

```

## 主题色

组件提供了两个不同的主题：`dark` 和 `light`，默认使用`light`。

```schema: scope="body"
[
  {
    "type": "tooltip-wrapper",
    "title": "标题",
    "content": "文案提示",
    "inline": true,
    "className": "mr-2",
    "body": [
      {
        "type": "tpl",
        "tpl": "light主题提示"
      }
    ]
  },
  {
    "type": "tooltip-wrapper",
    "title": "标题",
    "content": "文案提示",
    "inline": true,
    "tooltipTheme": "dark",
    "body": [
      {
        "type": "tpl",
        "tpl": "dark主题提示"
      }
    ]
  }
]

```

## 延迟打开&关闭

`mouseEnterDelay` 为延迟展示, `mouseLeaveDelay` 为延迟隐藏，

```schema: scope="body"
[
  {
    "type": "tooltip-wrapper",
    "title": "标题",
    "content": "提示内容",
    "mouseEnterDelay": 1000,
    "mouseLeaveDelay": 2000,
    "inline": true,
    "className": "mr-2",
    "body": [
      {
        "type": "tpl",
        "tpl": "延迟1s展示，延迟2s隐藏"
      }
    ]
  }
]

```

## 动态文案

`content` 和 `title` 支持变量映射，可以从上下文中动态获取提示文案。

```schema
{
  "type": "page",
  "data": {
    "text": "The longest word in any of the major English language dictionaries is pneumonoultramicroscopicsilicovolcanoconiosis, a word that refers to a lung disease contracted from the inhalation of very fine silica particles, specifically from a volcano; medically, it is the same as silicosis."
  },
  body: {
    "type": "tooltip-wrapper",
    "content": "${text}",
    "body": {
      "type": "html",
      "style": {
        "overflow": "hidden",
        "textOverflow": "ellipsis",
        "whiteSpace": "nowrap",
        "maxWidth": "300px",
        "display": "inline-block"
      },
      "html": "${text}"
    }
  }
}
```

## 内联展示

设置`"inline": true`使容器内联展示

```schema: scope="body"
[
  {
    "type": "tooltip-wrapper",
    "content": "文字提示",
    "inline": true,
    "className": "p-1 mr-3 border-2 border-solid border-indigo-400",
    "body": "内联容器1"
  },
  {
    "type": "tooltip-wrapper",
    "content": "文字提示",
    "inline": true,
    "className": "p-1 mr-3 border-2 border-solid border-indigo-400",
    "body": "内联容器2"
  },
  {
    "type": "tooltip-wrapper",
    "content": "文字提示",
    "className": "p-1 mt-3 border-2 border-solid border-green-400",
    "body": "非内联容器"
  }
]

```

## 自定义样式

使用`style`控制内容区样式，`tooltipStyle`控制浮层区样式

```schema: scope="body"
{
  "type": "tooltip-wrapper",
  "content": "文字提示(加粗)",
  "inline": true,
  "style": {
    fontStyle: "italic"
  },
  "tooltipStyle": {
    fontWeight: "bold"
  },
  "body": [
    {
      "type": "tpl",
      "tpl": "一段文案"
    }
  ]
}
```

## 自定义包裹标签

使用`wrapperComponent`修改标签名，可以让容器使用其他标签渲染：

```schema: scope="body"
{
  "type": "tooltip-wrapper",
  "content": "文字提示",
  "wrapperComponent": "pre",
  "body": "function HelloWorld() {\n    console.log('Hello World');\n}"
}
```

## 属性表

| 属性名                | 类型                                                                    | 默认值              | 说明                                           |
| --------------------- | ----------------------------------------------------------------------- | ------------------- | ---------------------------------------------- |
| type                  | `string`                                                                | `"tooltip-wrapper"` | 指定为文字提示容器组件                         |
| title                 | `string`                                                                | `""`                | 文字提示标题                                   |
| content               | `string`                                                                | `""`                | 文字提示内容, 兼容之前的 tooltip 属性          |
| placement             | `"top" \| "left" \| "right" \| "bottom" `                               | `"top"`             | 文字提示浮层出现位置                           |
| tooltipTheme          | `"light" \| "dark"`                                                     | `"light"`           | 主题样式， 默认为 light                        |
| offset                | `[number, number]`                                                      | `[0, 0]`            | 文字提示浮层位置相对偏移量，单位 px            |
| showArrow             | `boolean`                                                               | `true`              | 是否展示浮层指向箭头                           |
| enterable             | `boolean`                                                               | `true`              | 是否鼠标可以移入到浮层中                       |
| disabled              | `boolean`                                                               | `false`             | 是否禁用浮层提示                               |
| trigger               | `"hover" \| "click" \| "focus" \| Array<"hover" \| "click" \| "focus">` | `"hover"`           | 浮层触发方式，支持数组写法`["hover", "click"]` |
| mouseEnterDelay       | `number`                                                                | `0`                 | 浮层延迟展示时间，单位 ms                      |
| mouseLeaveDelay       | `number`                                                                | `300`               | 浮层延迟隐藏时间，单位 ms                      |
| rootClose             | `boolean`                                                               | `true`              | 是否点击非内容区域关闭提示                     |
| inline                | `boolean`                                                               | `false`             | 内容区是否内联显示                             |
| wrapperComponent      | `string`                                                                | `"div" \| "span"`   | 容器标签名                                     |
| body                  | [SchemaNode](../../docs/types/schemanode)                               | -                   | 内容容器                                       |
| style                 | `Object` \| `string`                                                    |                     | 内容区自定义样式                               |
| tooltipStyle          | `Object` \| `string`                                                    |                     | 浮层自定义样式                                 |
| className             | `string`                                                                |                     | 内容区类名                                     |
| tooltipClassName      | `string`                                                                |                     | 文字提示浮层类名                               |
| tooltipArrowClassName | `string`                                                                |                     | 箭头类名                                       |

---

### Zh CN Components Tpl (`docs/zh-CN/components/tpl.md`)

---
title: Tpl 模板
description:
type: 0
group: ⚙ 组件
menuName: Tpl
icon:
order: 70
---

输出 [模板](../../docs/concepts/template) 的常用组件

## 基本用法

```schema
{
  "data": {
    "text": "World!"
  },
  "type": "page",
  "body": {
    "type": "tpl",
    "tpl": "Hello ${text}"
  }
}
```

更多模板相关配置请看[模板文档](../../docs/concepts/template)

## 属性表

| 属性名          | 类型                                 | 默认值  | 说明                                         |
| --------------- | ------------------------------------ | ------- | -------------------------------------------- |
| type            | `string`                             | `"tpl"` | 指定为 Tpl 组件                              |
| className       | `string`                             |         | 外层 Dom 的类名                              |
| tpl             | [模板](../../docs/concepts/template) |         | 配置模板                                     |
| showNativeTitle | `boolean`                            |         | 是否设置外层 DOM 节点的 title 属性为文本内容 |

## 事件表

> 2.5.3 及以上版本

当前组件会对外派发以下事件，可以通过`onEvent`来监听这些事件，并通过`actions`来配置执行的动作，在`actions`中可以通过`${事件参数名}`或`${event.data.[事件参数名]}`来获取事件产生的数据，详细查看[事件动作](../../docs/concepts/event-action)。

| 事件名称   | 事件参数 | 说明           |
| ---------- | -------- | -------------- |
| click      | -        | 点击时触发     |
| mouseenter | -        | 鼠标移入时触发 |
| mouseleave | -        | 鼠标移出时触发 |

### click

鼠标点击。可以尝试通过`${event.context.nativeEvent}`获取鼠标事件对象。

```schema: scope="body"
{
    "type": "tpl",
    "tpl": "Hello",
    "onEvent": {
        "click": {
            "actions": [
            {
                "actionType": "toast",
                "args": {
                "msgType": "info",
                "msg": "${event.context.nativeEvent.type}"
                }
            }
            ]
        }
    }
}
```

### mouseenter

鼠标移入。可以尝试通过`${event.context.nativeEvent}`获取鼠标事件对象。

```schema: scope="body"
{
   "type": "tpl",
    "tpl": "Hello",
    "onEvent": {
        "mouseenter": {
        "actions": [
            {
            "actionType": "toast",
            "args": {
                "msgType": "info",
                "msg": "${event.context.nativeEvent.type}"
            }
            }
        ]
        }
    }
}
```

### mouseleave

鼠标移出。可以尝试通过`${event.context.nativeEvent}`获取鼠标事件对象。

```schema: scope="body"
{
   "type": "tpl",
    "tpl": "Hello",
    "onEvent": {
        "mouseleave": {
        "actions": [
            {
            "actionType": "toast",
            "args": {
                "msgType": "info",
                "msg": "${event.context.nativeEvent.type}"
            }
            }
        ]
        }
    }
}
```

---

### Zh CN Components Video (`docs/zh-CN/components/video.md`)

---
title: Video 视频
description:
type: 0
group: ⚙ 组件
menuName: Video
icon:
order: 71
---

## 基本用法

```schema: scope="body"
{
    "type": "video",
    "src": "raw:https://amis.bj.bcebos.com/amis/2019-12/1577157317579/trailer_hd.mp4",
    "poster": "raw:https://internal-amis-res.cdn.bcebos.com/images/2019-12/1577157239810/da6376bf988c.png"
}
```

## flv 和 hls 直播

需要设置 `isLive: true`，目前 flv 和 hls 是通过文件后缀来判断的，还可以通过设置 videoType 来指定，它有两个值：

- `video/x-flv`，使用 [mpegts.js](https://github.com/xqq/mpegts.js) 播放 flv
- `application/x-mpegURL`，使用 [hls.js](https://github.com/video-dev/hls.js/) 播放 hls 格式

## 视频帧切换功能

可以定义一组视频帧，渲染的时候会列出来这些帧，点击的时候会自动跳转到对应位置开始播放。

```schema: scope="body"
{
    "type": "video",
    "src": "https://amis.bj.bcebos.com/amis/2019-12/1577157317579/trailer_hd.mp4",
    "poster": "https://internal-amis-res.cdn.bcebos.com/images/2019-12/1577157239810/da6376bf988c.png",
    "jumpFrame": true,
    "jumpBufferDuration": 0,
    frames: {
        '00:10': '',
        '00:20': '',
        '00:30': ''
    },
}
```

可以设置帧图片如果有的话，这个示例偷懒直接用封面了。

```schema: scope="body"
{
    "type": "video",
    "src": "https://amis.bj.bcebos.com/amis/2019-12/1577157317579/trailer_hd.mp4",
    "poster": "https://internal-amis-res.cdn.bcebos.com/images/2019-12/1577157239810/da6376bf988c.png",
    "jumpFrame": true,
    "jumpBufferDuration": 0,
    stopOnNextFrame: true,
    frames: {
        '00:10': 'https://internal-amis-res.cdn.bcebos.com/images/2019-12/1577157239810/da6376bf988c.png',
        '00:20': 'https://internal-amis-res.cdn.bcebos.com/images/2019-12/1577157239810/da6376bf988c.png',
        '00:30': 'https://internal-amis-res.cdn.bcebos.com/images/2019-12/1577157239810/da6376bf988c.png'
    },
}
```

## 属性表

| 属性名             | 类型      | 默认值    | 说明                                                                      |
| ------------------ | --------- | --------- | ------------------------------------------------------------------------- |
| type               | `string`  | `"video"` | 指定为 video 渲染器                                                       |
| className          | `string`  |           | 外层 Dom 的类名                                                           |
| src                | `string`  |           | 视频地址                                                                  |
| isLive             | `boolean` | false     | 是否为直播，视频为直播时需要添加上，支持`flv`和`hls`格式                  |
| videoType          | `string`  |           | 指定直播视频格式                                                          |
| poster             | `string`  |           | 视频封面地址                                                              |
| muted              | `boolean` |           | 是否静音                                                                  |
| loop               | `boolean` |           | 是否循环播放                                                              |
| autoPlay           | `boolean` |           | 是否自动播放                                                              |
| rates              | `array`   |           | 倍数，格式为`[1.0, 1.5, 2.0]`                                             |
| frames             | `object`  |           | key 是时刻信息，value 可以为空，也可设置为图片地址，请看上方示例          |
| jumpBufferDuration | `boolean` |           | 点击帧的时候默认是跳转到对应的时刻，如果想提前 3 秒钟，可以设置这个值为 3 |
| stopOnNextFrame    | `boolean` |           | 到了下一帧默认是接着播放，配置这个会自动停止                              |

---

### Zh CN Components Web Component (`docs/zh-CN/components/web-component.md`)

---
title: Web Component
description:
type: 0
group: ⚙ 组件
menuName: WebComponent
icon:
order: 73
---

专门用来渲染 web component 的组件，可以通过这种方式来扩展 amis 组件，比如使用 Angular。

## 基本用法

比如下面这个 web component

```html
<random-number prefix="hello" class="my-class"></random-number>
```

对应代码类似

```javascript
import '@webcomponents/webcomponentsjs/custom-elements-es5-adapter';

class RandomNumber extends HTMLElement {
  connectedCallback() {
    const prefix = this.getAttribute('prefix') || '';
    const shadow = this.attachShadow({mode: 'open'});
    const text = document.createElement('span');
    text.textContent = `${prefix}: ${Math.floor(Math.random() * 1000)}`;
    shadow.appendChild(text);
    setInterval(function () {
      const count = `${prefix}: ${Math.floor(Math.random() * 1000)}`;
      text.textContent = count;
    }, 2000);
  }
}

customElements.define('random-number', RandomNumber);
```

使用 amis 可以这样渲染出来

```json
{
  "type": "web-component",
  "tag": "random-number",
  "props": {
    "prefix": "hello",
    "class": "my-class"
  }
}
```

其中 `tag` 指定标签，属性放在 `props` 对象里，props 里的值支持变量替换，比如：

```json
{
  "data": {
    "text": "World"
  },
  "type": "page",
  "body": {
    "type": "web-component",
    "tag": "random-number",
    "props": {
      "prefix": "${text}"
    }
  }
}
```

## 属性表

| 属性名 | 类型                                      | 默认值            | 说明                          |
| ------ | ----------------------------------------- | ----------------- | ----------------------------- |
| type   | `string`                                  | `"web-component"` | 指定为 web-component 渲染器   |
| tag    | `string`                                  |                   | 具体使用的 web-component 标签 |
| props  | `object`                                  |                   | 标签上的属性                  |
| body   | [SchemaNode](../../docs/types/schemanode) |                   | 子节点                        |

---

### Zh CN Components Wizard (`docs/zh-CN/components/wizard.md`)

---
title: Wizard 向导
description:
type: 0
group: ⚙ 组件
menuName: Wizard 向导
icon:
order: 73
---

表单向导，能够配置多个步骤引导用户一步一步完成表单提交。

## 基本使用

```schema: scope="body"
{
    "type": "wizard",
    "initApi": "/api/mock2/form/saveForm?waitSeconds=2",
    "steps": [
        {
            "title": "第一步",
            "body": [
                {
                    "name": "website",
                    "label": "网址",
                    "type": "input-url",
                    "required": true
                },
                {
                    "name": "email",
                    "label": "邮箱",
                    "type": "input-email",
                    "required": true
                }
            ]
        },
        {
            "title": "Step 2",
            "body": [
                {
                    "name": "email2",
                    "label": "邮箱",
                    "type": "input-email",
                    "required": true
                }
            ]
        },
        {
            "title": "Step 3",
            "body": [
                "这是最后一步了"
            ]
        }
    ]
}
```

## 自定义按钮

可以在每个 `step` 中配置 `actions` 来自定义按钮。按钮所在数据域查看`WizardActionData`定义（`3.5.0`及以上版本支持）

```typescript
interface WizardActionData {
  /* 当前步骤数值，从1开始 */
  currentStep: number;
}
```

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 初始化到某一步

`initApi` 接口返回 `step` 字段即可，注意得是数字类型。`1` 表示第一步，`2` 表示第二步，以此类推

```schema: scope="body"
{
    "type": "wizard",
    "initApi": "/api/mock2/initWizard",
    "steps": [
        {
            "title": "第一步",
            "body": [
                {
                    "name": "website",
                    "label": "网址",
                    "type": "input-url",
                    "required": true
                },
                {
                    "name": "email",
                    "label": "邮箱",
                    "type": "input-email",
                    "required": true
                }
            ]
        },
        {
            "title": "Step 2",
            "body": [
                {
                    "name": "email2",
                    "label": "邮箱",
                    "type": "input-email",
                    "required": true
                }
            ]
        },
        {
            "title": "Step 3",
            "body": [
                "这是最后一步了"
            ]
        }
    ]
}
```

## 限制跳转

可以通过在 step 上配置 `jumpableOn` 来限制跳转，可以基于整体 wizard 数据，或者基于 `currentStep` 来判断。

比如：`"jumpableOn": "${!website}",` 当设置完成了 website 后不可以回去跳转

```schema: scope="body"
{
    "type": "wizard",
    "initApi": "/api/mock2/initWizard",
    "steps": [
        {
            "title": "第一步",
            "jumpableOn": "${!website}",
            "body": [
                {
                    "name": "website",
                    "label": "网址",
                    "type": "input-url",
                    "required": true
                },
                {
                    "name": "email",
                    "label": "邮箱",
                    "type": "input-email",
                    "required": true
                }
            ]
        },
        {
            "title": "Step 2",
            "body": [
                {
                    "name": "email2",
                    "label": "邮箱",
                    "type": "input-email",
                    "required": true
                }
            ]
        },
        {
            "title": "Step 3",
            "body": [
                "这是最后一步了"
            ]
        }
    ]
}
```

## 属性表

| 属性名              | 类型                                     | 默认值               | 说明                                                                                                                                                     |
| ------------------- | ---------------------------------------- | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| type                | `string`                                 | `"wizard"`           | 指定为 `Wizard` 组件                                                                                                                                     |
| mode                | `string`                                 | `"horizontal"`       | 展示模式，选择：`horizontal` 或者 `vertical`                                                                                                             |
| api                 | [API](../../docs/types/api)              |                      | 最后一步保存的接口。                                                                                                                                     |
| initApi             | [API](../../docs/types/api)              |                      | 初始化数据接口                                                                                                                                           |
| initFetch           | [API](../../docs/types/api)              |                      | 初始是否拉取数据。                                                                                                                                       |
| initFetchOn         | [表达式](../../docs/concepts/expression) |                      | 初始是否拉取数据，通过表达式来配置                                                                                                                       |
| actionPrevLabel     | `string`                                 | `上一步`             | 上一步按钮文本                                                                                                                                           |
| actionNextLabel     | `string`                                 | `下一步`             | 下一步按钮文本                                                                                                                                           |
| actionNextSaveLabel | `string`                                 | `保存并下一步`       | 保存并下一步按钮文本                                                                                                                                     |
| actionFinishLabel   | `string`                                 | `完成`               | 完成按钮文本                                                                                                                                             |
| className           | `string`                                 |                      | 外层 CSS 类名                                                                                                                                            |
| actionClassName     | `string`                                 | `btn-sm btn-default` | 按钮 CSS 类名                                                                                                                                            |
| reload              | `string`                                 |                      | 操作完后刷新目标对象。请填写目标组件设置的 name 值，如果填写为 `window` 则让当前页面整体刷新。                                                           |
| redirect            | [模板](../../docs/concepts/template)     | `3000`               | 操作完后跳转。                                                                                                                                           |
| target              | `string`                                 | `false`              | 可以把数据提交给别的组件而不是自己保存。请填写目标组件设置的 name 值，如果填写为 `window` 则把数据同步到地址栏上，同时依赖这些数据的组件会自动重新刷新。 |
| steps               | Array<[step](#step)>                     |                      | 数组，配置步骤信息                                                                                                                                       |
| startStep           | `string`                                 | `1`                  | 起始默认值，从第几步开始。可支持模版，但是只有在组件创建时渲染模版并设置当前步数，在之后组件被刷新时，当前 step 不会根据 startStep 改变                  |

### step

| 属性名              | 类型                                     | 默认值 | 说明                                                                                                        |
| ------------------- | ---------------------------------------- | ------ | ----------------------------------------------------------------------------------------------------------- |
| title               | `string`                                 |        | 步骤标题                                                                                                    |
| mode                | `string`                                 |        | 展示默认，跟 [Form](./Form/Form) 中的模式一样，选择： `normal`、`horizontal`或者`inline`。                  |
| horizontal          | `Object`                                 |        | 当为水平模式时，用来控制左右占比                                                                            |
| horizontal.label    | `number`                                 |        | 左边 label 的宽度占比                                                                                       |
| horizontal.right    | `number`                                 |        | 右边控制器的宽度占比。                                                                                      |
| horizontal.offset   | `number`                                 |        | 当没有设置 label 时，右边控制器的偏移量                                                                     |
| api                 | [API](../../docs/types/api)              |        | 当前步骤保存接口，可以不配置。                                                                              |
| initApi             | [API](../../docs/types/api)              |        | 当前步骤数据初始化接口。                                                                                    |
| initFetch           | `boolean`                                |        | 当前步骤数据初始化接口是否初始拉取。                                                                        |
| initFetchOn         | [表达式](../../docs/concepts/expression) |        | 当前步骤数据初始化接口是否初始拉取，用表达式来决定。                                                        |
| body                | Array<[FormItem](./form/formItem)>       |        | 当前步骤的表单项集合，请参考 [FormItem](./form/formItem)。                                                  |
| closeDialogOnSubmit | `boolean`                                |        | 提交的时候是否关闭弹窗。当 widzard 里面有且只有一个弹窗的时候，本身提交会触发弹窗关闭，此属性可以关闭此行为 |
| jumpableOn          | `string`                                 |        | 配置是否可跳转的表达式                                                                                      |
| actions             | `Array<Schema>`                          |        | 自定义每一步的操作按钮                                                                                      |

## 事件表

当前组件会对外派发以下事件，可以通过`onEvent`来监听这些事件，并通过`actions`来配置执行的动作，在`actions`中可以通过`${事件参数名}`或`${event.data.[事件参数名]}`来获取事件产生的数据，详细请查看[事件动作](../../docs/concepts/event-action)。

> `[name]`为当前数据域中的字段名，例如：当前数据域为 {username: 'amis'}，则可以通过${username}获取对应的值。

| 事件名称       | 事件参数                                                                                                                                                                                   | 说明                       |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------- |
| inited         | `responseData: any` 请求的响应数据</br>`responseStatus: number` 响应状态，0 表示成功</br>`responseMsg: string`响应消息, `error`表示接口是否成功<br/>`[name]: any` 当前数据域中指定字段的值 | initApi 接口请求完成时触发 |
| stepChange     | `step: number` 步骤索引                                                                                                                                                                    | 切换步骤时触发             |
| change         | `event.data: object` 当前表单数据<br/>`[name]: any` 当前数据域中指定字段的值                                                                                                               | 表单值变化时触发           |
| stepSubmitSucc | -                                                                                                                                                                                          | 单个步骤提交成功           |
| stepSubmitFail | `error: object` 单个步骤 api 远程请求失败后返回的错误信息                                                                                                                                  | 单个步骤提交失败           |
| finished       | `event.data: object` 即将提交的表单数据<br/>`[name]: any` 当前数据域中指定字段的值                                                                                                         | 最终提交时触发             |
| submitSucc     | `result: object` api 远程请求成功后返回的结果数据                                                                                                                                          | 最终提交成功时触发         |
| submitFail     | `error: object` api 远程请求失败后返回的错误信息                                                                                                                                           | 最终提交失败时触发         |

## 动作表

当前组件对外暴露以下特性动作，其他组件可以通过指定`actionType: 动作名称`、`componentId: 该组件id`来触发这些动作，动作配置可以通过`args: {动作配置项名称: xxx}`来配置具体的参数，详细请查看[事件动作](../../docs/concepts/event-action#触发其他组件的动作)。

| 动作名称    | 动作配置                   | 说明                                     |
| ----------- | -------------------------- | ---------------------------------------- |
| submit      | -                          | 全部提交                                 |
| step-submit | -                          | 分步提交                                 |
| next        | -                          | 下一步                                   |
| prev        | -                          | 上一步                                   |
| goto-step   | `step: number` 目标步骤    | 定位步骤                                 |
| reload      | -                          | 重新加载，调用 `intiApi`，刷新数据域数据 |
| setValue    | `value: object` 更新的数据 | 更新数据                                 |

---

### Zh CN Components Wrapper (`docs/zh-CN/components/wrapper.md`)

---
title: Wrapper 包裹容器
description:
type: 0
group: ⚙ 组件
menuName: Wrapper
icon:
order: 72
---

简单的一个包裹容器组件，相当于用 div 包含起来，最大的用处是用来配合 css 进行布局。

## 基本用法

```schema: scope="body"
{
    "type": "wrapper",
    "body": "内容",
    "className": "b"
}
```

> 上面例子中的 `"className": "b"` 是为了增加边框，不然看不出来。

## 动态获取

直接返回一个对象

```schema: scope="body"
{
  "type": "page",
  "data": {
    "style": {
      "color": "#aaa"
    }
  },
  "body": [
    {
      "type": "wrapper",
      "body": "内容",
      "className": "b",
      "style": "${style}"
    }
  ]
}
```

返回变量

```schema: scope="body"
{
  "type": "page",
  "data": {
    "color": "#aaa"
  },
  "body": [
    {
      "type": "wrapper",
      "body": "内容",
      "className": "b",
      "style": {
        "color": "${color}",
        "fontSize": "30px"
      }
    }
  ]
}
```

## 不同内边距

通过配置`size`属性，可以调整内边距

```schema: scope="body"
[
  {
    "type": "wrapper",
    "body": "默认内边距",
    "className": "b"
  },
  {
    "type": "divider"
  },
  {
    "type": "wrapper",
    "body": "极小的内边距",
    "size": "xs",
    "className": "b"
  },
  {
    "type": "divider"
  },
  {
    "type": "wrapper",
    "body": "小的内边距",
    "size": "sm",
    "className": "b"
  },
  {
    "type": "divider"
  },
  {
    "type": "wrapper",
    "body": "中等的内边距",
    "size": "md",
    "className": "b"
  },
  {
    "type": "divider"
  },
  {
    "type": "wrapper",
    "body": "大的内边距",
    "size": "lg",
    "className": "b"
  },
  {
    "type": "divider"
  },
  {
    "type": "wrapper",
    "body": "无内边距",
    "size": "none",
    "className": "b"
  }
]
```

## style

> 1.1.5 版本

wrapper 可以设置 style，当成一个 `div` 标签来用

## 属性表

| 属性名    | 类型                                      | 默认值      | 说明                         |
| --------- | ----------------------------------------- | ----------- | ---------------------------- |
| type      | `string`                                  | `"wrapper"` | 指定为 Wrapper 渲染器        |
| className | `string`                                  |             | 外层 Dom 的类名              |
| size      | `string`                                  |             | 支持: `xs`、`sm`、`md`和`lg` |
| style     | `Object` \| `string`                      |             | 自定义样式                   |
| body      | [SchemaNode](../../docs/types/schemanode) |             | 内容容器                     |

---

### Zh CN Concepts Action (`docs/zh-CN/concepts/action.md`)

---
title: 行为
description:
type: 0
group: 💡 概念
menuName: 行为
icon:
order: 12
---

页面的交互操作，例如：**提交表单、显示一个弹框、跳转页面、复制一段文字到粘贴板**等等操作，都可以视作页面的一种**行为**。

在 amis 中，大部分 **行为** 是跟 **行为按钮组件** 进行绑定的，也就是说，当你想要配置一个行为，大部分情况下你应该遵循下面的步骤：

1. 添加一个 **行为按钮组件**；
2. 配置当前 **行为类型（actionType）**；
3. 根据当前行为类型，配置你想要的 **属性**。

## 如何配置行为？

### 通过行为按钮

```schema: scope="body"
{
    "type": "action",
    "label": "发出一个请求",
    "actionType": "ajax",
    "api": "/api/mock2/form/saveForm"
}
```

1. 在`page`内容区中，添加一个`action`行为按钮组件
2. 配置当前行为类型是 ajax（即发送一个 ajax 请求)
3. 配置请求 api，值为 API 类型

现在点击该按钮，你会发现浏览器发出了这个`ajax`请求。

很简单是吧？我们再来一个例子：

```schema: scope="body"
{
    "type": "action",
    "label": "弹个框",
    "actionType": "dialog",
    "dialog": {
      "title": "弹框",
      "body": "Hello World!"
    }
}
```

这次我们配置`actionType`为`dialog`，意味着点击该按钮会弹出一个模态框，并配置`dialog`内容，来显示字符串`Hello World!`

> `dialog`是容器，也就意味着可以在`body`属性中配置其他组件

完整的行为列表可以查看 [action](../../components/action)组件

### 组件所支持的行为

一些特殊组件，例如 Chart 组件 中的图表点击行为，可以直接配置`clickAction`，来配置行为对象。

---

### Zh CN Concepts Data Mapping (`docs/zh-CN/concepts/data-mapping.md`)

---
title: 数据映射
description:
type: 0
group: 💡 概念
menuName: 数据映射
icon:
order: 12
---

数据映射支持用户通过`${xxx}`或`$xxx`获取当前数据链中某个变量的值，实现灵活的数据配置功能，主要用于模板字符串、 自定义 `api` 请求数据体格式等场景。

## 模板字符串

```schema
{
  "type": "page",
  "data": {
    "name": "rick"
  },
  "body": [
    {
      "type": "tpl",
      "tpl": "my name is ${name}" // 输出: my name is rick
    }
  ]
}
```

**tip：** 默认 amis 在解析模板字符串时，遇到`$`字符会尝试去解析该变量并替换改模板变量，如果你想输出纯文本`"${xxx}"`或`"$xxx"`，那么需要在`$`前加转义字符`"\\"`，即`"\\${xxx}"`

```schema
{
  "type": "page",
  "data": {
    "name": "rick"
  },
  "body": {
    "type": "tpl",
    "tpl": "my name is \\${name}"
  }
}
```

## 支持链式取值

可以使用`.`进行链式取值

```schema
{
  "type": "page",
  "data": {
    "name": "rick",
    "company": {
      "name": "baidu",
      "department": "it"
    }
  },
  "body": {
    "type": "tpl",
    "tpl": "my name is ${name}, I work for ${company.name}" // 输出 my name is rick, I work for baidu
  }
}
```

## 自定义 api 请求体数据格式

在表单提交接口时，amis 默认的请求体数据格式可能不符合你的预期，不用担心，你可以使用数据映射定制想要的数据格式：

查看下面这种场景：

```schema: scope="body"
{
    "type": "form",
    "api": "/api/mock2/form/saveForm",
    "body": [
      {
        "type": "input-text",
        "name": "name",
        "label": "姓名："
      },
      {
        "name": "email",
        "type": "input-text",
        "label": "邮箱："
      }
    ]
}
```

当输入姓名：`rick` 和邮箱：`rick@gmail.com` 后，`form` 获取当前的数据域，提交后端接口的数据格式应该是这样的：

```json
{
  "name": "rick",
  "email": "rick@gmail.com"
}
```

遗憾的是，你的后端接口只支持的如下的输入数据结构，且无法修改：

```json
{
  "userName": "xxx",
  "userEmail": "xxx@xxx.com"
}
```

这时，除了直接更改你的 姓名表单项 和 邮箱表单项 的`name`属性为相应的字段以外，你可以配置`api`的`data`属性，使用**数据映射**轻松实现**数据格式的自定义：**

```schema: scope="body"
{
    "type": "form",
    "api": {
        "method": "post",
        "url": "/api/mock2/form/saveForm",
        "data": {
            "userName": "${name}",
            "userEmail": "${email}"
        }
    },
    "body": [
      {
        "type": "input-text",
        "name": "name",
        "label": "姓名："
      },
      {
        "name": "email",
        "type": "input-text",
        "label": "邮箱："
      }
    ]
}
```

你可以查看网络面板，发送给后端接口的数据体应该已经成功修改为：

```json
{
  "userName": "rick",
  "userEmail": "rick@gmail.com"
}
```

## 复杂配置

### 展开所配置的数据

可以使用`"&"`，作为数据映射 key，展开所配置的变量，例如：

下面例子中，我们想在提交的时候，除了提交 `name` 和 `email` 变量以外，还想添加 `c` 下面的所有变量 `e`,`f`,`g`，但是按照之前所讲的， api 应该这么配置：

```schema: scope="body"
{
  "type": "form",
  "data": {
    "a": "1",
    "b": "2",
    "c": {
      "e": "3",
      "f": "4",
      "g": "5"
    }
  },
  "api": {
    "url": "/api/mock2/form/saveForm",
    "method": "post",
    "data": {
      "name": "${name}",
      "email": "${email}",
      "e": "${c.e}",
      "f": "${c.f}",
      "g": "${c.g}"
    }
  },
  "body": [
    {
      "type": "input-text",
      "name": "name",
      "label": "姓名："
    },
    {
      "name": "email",
      "type": "input-text",
      "label": "邮箱："
    }
  ]
}
```

点击提交查看网络面板数据，你会发现数据是符合预期的：

```json
{
  "name": "rick",
  "email": "rick@gmail.comn",
  "e": "3",
  "f": "4",
  "g": "5"
}
```

但是当变量字段过多的时候，你需要一一映射配置，也许有点麻烦，所以可以使用`"&"`标识符，来展开所配置变量：

```schema: scope="body"
{
  "type": "form",
  "data": {
    "a": "1",
    "b": "2",
    "c": {
      "e": "3",
      "f": "4",
      "g": "5"
    }
  },
  "api": {
    "url": "/api/mock2/form/saveForm",
    "method": "post",
    "data": {
      "name": "${name}",
      "email": "${email}",
      "&": "${c}"
    }
  },
  "body": [
    {
      "type": "input-text",
      "name": "name",
      "label": "姓名："
    },
    {
      "name": "email",
      "type": "input-text",
      "label": "邮箱："
    }
  ]
}
```

上例中我们 api.data 配置如下：

```json
"data": {
  "name": "${name}",
  "email": "${email}",
  "&": "${c}"
}
```

`"&"`标识符会将所配置的`c`变量的`value`值，展开并拼接在`data`中。查看网络面板可以看到数据如下：

```json
{
  "name": "rick",
  "email": "rick@gmail.comn",
  "e": "3",
  "f": "4",
  "g": "5"
}
```

### 数组提取值

```schema: scope="body"
{
    "type": "form",
    "api": {
        "method": "post",
        "url": "/api/mock2/form/saveForm",
        "data": {
            "items": {
              "$table": {
                "a": "${a}",
                "c": "${c}"
              }
            }
        }
    },
    "body": [
      {
        "type": "input-table",
        "name": "table",
        "label": "table",
        "columns": [
          {
            "label": "A",
            "name": "a"
          },
          {
            "label": "B",
            "name": "b"
          },
          {
            "label": "C",
            "name": "c"
          }
        ],
        "value": [
          {
            "a": "a1",
            "b": "b1",
            "c": "c1"
          },
          {
            "a": "a2",
            "b": "b2",
            "c": "c2"
          },
          {
            "a": "a3",
            "b": "b3",
            "c": "c3"
          }
        ]
      }
    ]
}
```

上例中的`api`的`data`配置格式如下：

```json
"data": {
    "items": {
      "$table": {
        "a": "${a}",
        "c": "${c}"
      }
    }
}
```

这个配置的意思是，只提取`table`数组中的`a`变量和`c`变量，组成新的数组，赋值给`items`变量

点击提交，查看浏览器网络面板可以发现，表单的提交数据结构如下：

```json
{
  "items": [
    {
      "a": "a1",
      "c": "c1"
    },
    {
      "a": "a2",
      "c": "c2"
    },
    {
      "a": "a3",
      "c": "c3"
    }
  ]
}
```

### namespace

> since 1.1.6

默认取值都是从当前组件上下文数据链中取数据，但是有些数据可能不在这个数据链中，比如有些数据存在全局变量，有的数据存在 localstorage 中。

从 1.1.6 版本开始，支持了一种新的语法如：`${window:document.title}` 意思是从全局变量中取页面的标题。

目前有以下三种 namespace

- `window` 即全局变量
- `ls` 即 localStorage， 如果值是 json 对象，可以直接当对象用比如：`${ls:xxxxxlocalStrorageKey.xxxx}`
- `ss` 即 sessionStorage，同上。
- `cookie` 即 cookies，同上。

```schema
{
  "type": "page",
  "body": "当前页面标题为：<span class='label label-info'>${window:document[title]}</span>"
}
```

## 过滤器

1.5.0 开始，更推荐用函数调用的语法来写，如 `${xxx | html}` 改用 `${html(xxx)}`。具体请查看[新表达式语法](./expression#新表达式语法)

过滤器是对数据映射的一种增强，它的作用是对获取数据做一些处理，基本用法如下：

```
${xxx [ |filter1 |filter2...] }
```

下面我们会逐一介绍每一个过滤器的用法。

> 过滤器可以 [串联使用](#串联使用过滤器)

### html

用于显示 html 文本。

##### 基本用法

```
${xxx | html}
```

```schema
{
  "type": "page",
  "data": {
    "html": "<div>这是一段<code>html</code></div>"
  },
  "body": {
    "type": "tpl",
    "tpl": "html is: ${html|html}"
  }
}
```

### raw

不同场景下，在使用数据映射时，amis 可能默认会使用`html`过滤器对数据进行转义显示，这时如果想要输出原始文本，请配置`raw`过滤器。

##### 基本用法

使用`raw`可以直接输出原始文本

```
${xxx | raw}
```

```schema
{
  "type": "page",
  "data": {
    "html": "<div>这是一段<code>html</code></div>"
  },
  "body": {
    "type": "tpl",
    "tpl": "html is: ${html|raw}"
  }
}
```

> **注意！！！**
>
> `raw`过滤器虽然支持显示原始文本，也就意味着可以输出 HTML 片段，但是动态渲染 HTML 是非常危险的，容易导致 **XSS** 攻击。
>
> 因此在 使用`raw`过滤器的时候，请确保变量的内容可信，且永远不要渲染用户填写的内容。

### json

用于将数据转换为`json`格式字符串

##### 基本用法

```
${xxx | json[:tabSize]}
```

```schema
{
  "type": "page",
  "data": {
    "info": {
      "name": "rick",
      "company": "baidu"
    }
  },
  "body": {
    "type": "tpl",
    "tpl": "my info is ${info|json}" // 输出: my info is { "name": "rick", "company": "baidu" }
  }
}
```

##### 指定缩进数

```
${xxx|json:4} // 指定缩进为4个空格
```

### toJson

与[json](#json)相反，用于将`json`格式的字符串，转换为`javascript`对象

```
${xxx | toJson}
```

```schema
{
  "type": "page",
  "data": {
    "info": "{\"name\": \"rick\", \"company\": \"baidu\"}"
  },
  "body": {
    "type": "tpl",
    "tpl": "my info is ${info|toJson}"
  }
}
```

对`Javascript`的直接输出会显示`[object Object]`，你可以使用 [json 过滤器](./data-mapping#json) 来格式化显示`json`文本。

### toInt

字符串转整形数字，如果目标数据不是字符串则不处理。

```
${xxx | toInt}
```

### toFloat

字符串转浮点数字，如果目标数据不是字符串则不处理。

```
${xxx | toFloat}
```

### date

日期格式化过滤器，用于把特定时间值按指定格式输出。

##### 基本用法

```
${xxx | date[:format][:inputFormat]}
```

- **format**：需要展示的格式，默认为`LLL`，即本地化时间格式
- **inputFormat**：指定该变量值的格式，默认为`X`，即时间戳秒，具体参数的配置需要参考 [moment](https://momentjs.com/docs/)，下面是其它几种常见的格式：
  - `x`，毫秒
  - `YYYY-MM-DDTHH:mm:ssZ`，ISO8601 格式，其中 YYYY 是年，MM 是月，DD 是日，HH 是小时，mm 是分钟，ss 是秒

```schema
{
  "type": "page",
  "data": {
    "now": 1586865590
  },
  "body": {
    "type": "tpl",
    "tpl": "now is ${now|date}"
  }
}
```

```schema
{
  "type": "page",
  "data": {
    "now": 1586865590000
  },
  "body": {
    "type": "tpl",
    "tpl": "毫秒 ${now|date:LLL:x}"
  }
}
```

##### 配置输出格式

例如你想将某一个时间值，以 `2020-04-14` 这样的格式输出，那么查找 moment 文档可知配置格式应为 `YYYY-MM-DD`，即：

```schema
{
  "type": "page",
  "data": {
    "now": 1586865590
  },
  "body": {
    "type": "tpl",
    "tpl": "now is ${now|date:YYYY-MM-DD}" // 通过配置输出格式，输出: now is 2020-04-14
  }
}
```

##### 配置数据格式

如果你的数据值默认不是`X`格式（即时间戳格式），那么需要配置`inputformat`参数用于解析当前时间值，例如：

```schema
{
  "type": "page",
  "data": {
    "now": "2020/4/14 19:59:50" // 查阅 moment 文档可知，需要配置数据格式为 "YYYY/MM/DD HH:mm:ss"
  },
  "body": {
    "type": "tpl",
    "tpl": "now is ${now|date:LLL:YYYY/MM/DD HH\\:mm\\:ss}" // 配置输出格式和数据格式，输出: now is 2020年4月14日晚上7点59分
  }
}
```

> **注意：** 在过滤器参数中使用`:`字符，需要在前面加`\\`转义字符

### now

返回当前时间，注意这个是个过滤函数，不是变量，所以这个其实会导致前面的变量选择没有意义。

用法：

```
${_|now}
```

### toDate

将日期字符串转成日期对象, 第二个参数为字符串的日期格式类型。

用法：

```
${xxx | toDate:YYYY-MM-DD}
```

### dateModify

日期修改，将输入的日期对象修改后返回新的日期对象，支持四种操作符。

- `add` 加 n （秒|分钟|小时|天|月|季度|年）。
- `subtract` 减 n （秒|分钟|小时|天|月|季度|年）。
- `startOf` 修改成某个维度的开头。
- `endOf` 修改成某个纬度的结尾。

比如：

将 xxx 修改成 7 天前，假如值是 10 月 8 号，那么处理完后就是 10 月 1 号。

```
${xxx | dateModify:subtract:-7:day}
```

来个高级点的，比如我想返回个上个月开头的第一天。

```schema
{
  "type": "page",
  "body": "上个月第一天是：${_|now|dateModify:subtract:1:month|dateModify:startOf:month|date:YYYY-MM-DD HH\\:mm\\:ss}"
}
```

### fromNow

> 1.4.0 及以上版本

显示日期和现在的相对时间

```schema
{
  "type": "page",
  "data": {
    "oldDate": "2021-10-01"
  },
  "body": "${oldDate|fromNow}"
}
```

可以设置日期数据的格式，比如 X 是秒，其它格式细节参考 [moment](https://momentjs.com/docs/)。

```schema
{
  "type": "page",
  "data": {
    "oldDate": 1586865590
  },
  "body": "${oldDate|fromNow:X}"
}
```

### number

自动给数字加千分位。

##### 基本用法

```
${xxx | number}
```

```schema
{
  "type": "page",
  "data": {
    "price": 233333333
  },
  "body": {
    "type": "tpl",
    "tpl": "price is ${price|number}" // 输出: price is 233,333,333
  }
}
```

### trim

把变量值前后多余的空格去掉。

##### 基本用法

```
${xxx | trim}
```

### percent

##### 基本用法

```
${xxx | percent[:decimals]}
```

- **decimals**：指定小数点后`n`位数，默认为`0`

```schema
{
  "type": "page",
  "data": {
    "value": 0.8232343
  },
  "body": {
    "type": "tpl",
    "tpl": "value is ${value|percent}" // 输出: value is 82%
  }
}
```

##### 指定小数点后位数

```schema
{
  "type": "page",
  "data": {
    "value": 0.8232343
  },
  "body": {
    "type": "tpl",
    "tpl": "value is ${value|percent:2}" // 保留小数点后4位，输出: value is 82.32%
  }
}
```

### round

四舍五入取整

```
${xxx | round[:decimals]}
```

- **decimals**：指定小数点后`n`位小数，默认为`2`

```schema
{
  "type": "page",
  "data": {
    "number1": 2.3,
    "number2": 2.6
  },
  "body": {
    "type": "tpl",
    "tpl": "number1 is ${number1|round}, number2 is ${number2|round}" // 输出: number1 is 2.30, number2 is 2.60
  }
}
```

##### 指定小数点后位数

```schema
{
  "type": "page",
  "data": {
    "number": 2.6
  },
  "body": {
    "type": "tpl",
    "tpl": "number is ${number|round:0}" // 保留小数点后0位，输出: number is 3
  }
}
```

### truncate

当超出若干个字符时，后面的部分直接显示某串字符

##### 基本用法

```
${xxx | truncate[:length][:mask]}
```

- **length**：指定多长的字符后省略，默认为`200`
- **mask**：省略时显示的字符，默认为`"..."`

```schema
{
  "type": "page",
  "data": {
    "text": "这是一段非常长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长的文字"
  },
  "body": {
    "type": "tpl",
    "tpl": "text is ${text|truncate:10}" // 输出: text is 这是一段非常长长长长...
  }
}
```

### url_encode

效果同 [encodeURIComponent() - JavaScript | MDN](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent)

##### 基本用法

```
${xxx | url_encode}
```

### url_decode

效果同 [decodeURIComponent() - JavaScript | MDN](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent)，注意从`2.3.0`版本开始，不合法的输入会被转化为`undefined`。

##### 基本用法

```
${xxx | url_decode}
```

### default

当变量值为空时，显示其他值代替。

##### 基本用法

```
${xxx | default[:defaultValue]}
```

- **defaultValue**：显示的默认值

```schema
{
  "type": "page",
  "data": {
    "value": "" // 或者是 null 或 undefined
  },
  "body": {
    "type": "tpl",
    "tpl": "value is ${value|default:-}" // 输出: value is -
  }
}
```

### split

可以将字符传通过分隔符分离成数组

##### 基本用法

```
${xxx | split[:delimiter]}
```

- **delimiter**：分隔值，默认为`,`

```schema
{
  "type": "page",
  "data": {
    "array": "a,b,c"
  },
  "body": {
    "type": "tpl",
    "tpl": "array is ${array|split|json}" // 输出: array is ["a", "b", "c"]
  }
}
```

### join

当变量值是数组时，可以把内容连接起来。

##### 基本用法

```
${xxx | join[:separator]}
```

- **separator**：连接符，默认为`逗号`

```schema
{
  "type": "page",
  "data": {
    "array": ["a", "b", "c"]
  },
  "body": {
    "type": "tpl",
    "tpl": "array is ${array|join}"
  }
}
```

配置成空字符串

```schema
{
  "type": "page",
  "data": {
    "array": ["a", "b", "c"]
  },
  "body": {
    "type": "tpl",
    "tpl": "array is ${array|join:''}"
  }
}
```

配置成连接符

```schema
{
  "type": "page",
  "data": {
    "array": ["a", "b", "c"]
  },
  "body": {
    "type": "tpl",
    "tpl": "array is ${array|join:-}" // 输出: array is a,b,c
  }
}
```

### sortBy

对目标数组进行排序。

- **key** 字段名，可以是数字，支持层级。
- **method** 排序方式 `alpha` 或者 `numerical`
- **dir** 排序方式 `desc` 或者 `asc`

如：`${list|sortBy:value:numerical:desc}` 让 list 按 value 字段的数值倒序。

### topAndOther

取前多少个，剩下的归位一组比如：`${list|topAndOther:10:name:Others}`

对数组分为 10 组，前面 9 组分别拿前 9 个，最后一组将剩下的归为一组，并对每项做数字累加。

- **len** 分多少组
- **labelField** 默认为 `name`
- **restLabel** 默认为`其他`。

### unique

对目标数组进行去重。

- **key** 可选，不指定属性则直接对整个成员进行去重。

如：`${items|unique:name}` 返回一个新数组，并且对成员属性 name 进行了去重。

### first

获取数组中的第一个值

##### 基本用法

```
${xxx | first}
```

```schema
{
  "type": "page",
  "data": {
    "array": ["a", "b", "c"]
  },
  "body": {
    "type": "tpl",
    "tpl": "first element is ${array|first}" // 输出: first element is a
  }
}
```

### last

获取数组中的最后一个值

##### 基本用法

```
${xxx | last}
```

```schema
{
  "type": "page",
  "data": {
    "array": ["a", "b", "c"]
  },
  "body": {
    "type": "tpl",
    "tpl": "last element is ${array|last}" // 输出: last element is c
  }
}
```

### nth

获取数组中的第`n`个值

##### 基本用法

```
${xxx | nth[:nth]}
```

- **nth**：指定获取第几个值

```schema
{
  "type": "page",
  "data": {
    "array": ["a", "b", "c"]
  },
  "body": {
    "type": "tpl",
    "tpl": "second element is ${array|nth:1}" // 输出: second element is b
  }
}
```

**注意：** nth 配置`0`为获取第一个元素。

### pick

获取对象或数组中符合条件的筛选值

##### 基本用法

```
${xxx | pick[:path]}
```

- **path:** 指定筛选的模板，默认为`&`，即返回原数据

##### 在对象中获取某个 key 值

```schema
{
  "type": "page",
  "data": {
    "object": {
      "a": 1,
      "b": 2,
      "c": 3
    }
  },
  "body": {
    "type": "tpl",
    "tpl": "a value of object is ${object|pick:a}" // 输出: a value of object is 1
  }
}
```

##### 遍历对象数组获取指定值

```schema
{
  "type": "page",
  "data": {
    "array": [
      {
        "a": 1,
        "b": 2,
        "c": 3
      },
      {
        "a": 10,
        "b": 20,
        "c": 30
      },
      {
        "a": 100,
        "b": 200,
        "c": 300
      }
    ]
  },
  "body": {
    "type": "tpl",
    "tpl": "new array is ${array|pick:a|json}" // 输出: new array is [1, 10 ,100]
  }
}
```

##### 遍历数组对象，并自定义 key

```schema
{
  "type": "page",
  "data": {
    "array": [
      {
        "aaa": 1,
        "bbb": 2,
        "ccc": 3
      },
      {
        "aaa": 10,
        "bbb": 20,
        "ccc": 30
      },
      {
        "aaa": 100,
        "bbb": 200,
        "ccc": 300
      }
    ]
  },
  "body": {
    "type": "tpl",
    "tpl": "new array is ${array|pick:a~aaa,b~bbb|json}"
    // 输出: new array is  [ { "a": 1, "b": 2 }, { "a": 10, "b": 20 }, { "a": 100, "b": 200 } ]
  }
}
```

可以用变量 index 来获取下标。

### objectToArray

对象转换为数组

- key: 对象的键转换之后的字段名，默认是'label'
- value: 对象的值转换之后的字段名，默认是'value'

```
${xxx | objectToArray[:key][:value]}
```

```schema
{
  "type": "page",
  "data": {
    "row": {
      "a": "A",
      "b": "B",
      "c": "C"
    }
  },
  "body": {
    "type": "tpl",
    "tpl": "row is: ${row|objectToArray|json}"
  }
}
```

```schema
{
  "type": "page",
  "data": {
    "row": {
      "a": "A",
      "b": "B",
      "c": "C"
    }
  },
  "body": {
    "type": "tpl",
    "tpl": "row is: ${row|objectToArray:key:val|json}"
  }
}
```

### plus

加法运算比如加 2

```
${xxx|plus:2}
```

还可以是另一个变量，比如

```
${xxx|plus:yyy}
```

```schema
{
  "type": "page",
  "data": {
    "xxx": 10,
    "yyy": 2
  },
  "body": {
    "type": "tpl",
    "tpl": "${xxx|plus:yyy}"
  }
}
```

下面的减法乘法和除法也都支持变量

### minus

减法运算比如减 2

```
${xxx|minus:2}
```

### times

乘法运算

```
${xxx|times:2}
```

### division

除法运算

```
${xxx|division:2}
```

### sum

求和，通常操作对象是个数组，比如想把数组中成员对象字段 cost 中的数值求和。

```
${xxx|pick:cost|sum}
```

### abs

变成正数。

```
${xxx|abs}
```

### duration

秒值格式化成时间格式

##### 基本用法

```
${xxx | duration}
```

```schema
{
  "type": "page",
  "data": {
    "time1": 2,
    "time2": 67,
    "time3": 1111111
  },
  "body": [
    {
        "type": "tpl",
        "tpl": "time1 is ${time1|duration}"
    },
    {
        "type": "divider"
    },
    {
        "type": "tpl",
        "tpl": "time2 is ${time2|duration}"
    },
    {
        "type": "divider"
    },
    {
        "type": "tpl",
        "tpl": "time3 is ${time3|duration}"
    }
  ]
}
```

### bytes

字节格式化展示

##### 基本用法

```
${xxx | bytes}
```

```schema
{
  "type": "page",
  "data": {
    "bytes1": 2333,
    "bytes2": 2333333,
    "bytes3": 2333333333
  },
  "body": [
    {
        "type": "tpl",
        "tpl": "bytes1 is ${bytes1|bytes}"
    },
    {
        "type": "divider"
    },
    {
        "type": "tpl",
        "tpl": "bytes2 is ${bytes2|bytes}"
    },
    {
        "type": "divider"
    },
    {
        "type": "tpl",
        "tpl": "bytes3 is ${bytes3|bytes}"
    }
  ]
}
```

##### 指定换算间隔参数

```
${xxx | bytes[:step]}
```

```schema
{
  "type": "page",
  "data": {
    "bytes1": 2333,
    "bytes2": 2333333,
    "bytes3": 2333333333
  },
  "body": [
    {
        "type": "tpl",
        "tpl": "bytes1 is ${bytes1|bytes:1024}"
    },
    {
        "type": "divider"
    },
    {
        "type": "tpl",
        "tpl": "bytes2 is ${bytes2|bytes:1024}"
    },
    {
        "type": "divider"
    },
    {
        "type": "tpl",
        "tpl": "bytes3 is ${bytes3|bytes:1024}"
    }
  ]
}
```

### asArray

将数据包成数组

##### 基本用法

```
${xxx | asArray}
```

```schema
{
  "type": "page",
  "data": {
    "value": "a"
  },
  "body": {
    "type": "tpl",
    "tpl": "new value is ${value|asArray|json}" // 输出: new value is ["a"]
  }
}
```

### lowerCase

将字符串转小写

##### 基本用法

```
${xxx | lowerCase}
```

```schema
{
  "type": "page",
  "data": {
    "text": "World"
  },
  "body": {
    "type": "tpl",
    "tpl": "Hello ${text|lowerCase}" // 输出: Hello world
  }
}
```

### upperCase

将字符串转大写

##### 基本用法

```
${xxx | upperCase}
```

```schema
{
  "type": "page",
  "data": {
    "text": "World"
  },
  "body": {
    "type": "tpl",
    "tpl": "Hello ${text|upperCase}" // 输出: Hello WORLD
  }
}
```

### substring

> 1.5.0 及以上版本

取字符串的一部分，第一个参数是起始，第二个参数的结束

##### 基本用法

下面写法将会取前两个字符

```
${xxx | substring:0:2}
```

```schema
{
  "type": "page",
  "data": {
    "text": "World"
  },
  "body": {
    "type": "tpl",
    "tpl": "Hello ${text|substring:0:2}"
  }
}
```

### base64Encode

base64 加密

##### 基本用法

```
${xxx | base64Encode}
```

```schema
{
  "type": "page",
  "data": {
    "text": "World"
  },
  "body": {
    "type": "tpl",
    "tpl": "Hello ${text|base64Encode}" // 输出: Hello V29ybGQ=
  }
}
```

### base64Decode

base64 解密

##### 基本用法

```
${xxx | base64Decode}
```

```schema
{
  "type": "page",
  "data": {
    "text": "V29ybGQ="
  },
  "body": {
    "type": "tpl",
    "tpl": "Hello ${text|base64Decode}" // 输出: Hello World
  }
}
```

### isTrue

真值条件过滤器

##### 基本用法

```
${xxx | isTrue[:trueValue][:falseValue]
```

- **trueValue**: 如果变量为 [真](https://developer.mozilla.org/zh-CN/docs/Glossary/Truthy)，即返回该值；
- **falseValue**: 如果变量为 [假](https://developer.mozilla.org/en-US/docs/Glossary/Falsy)，则返回该值。

> 配置`trueValue`和`falseValue`时，如果想要返回当前数据域中某个变量的值，那么参数可以直接配置变量名而不需要在两边添加引号；如果想返回某字符串，那么需要给参数两边添加单引号或双引号，
>
> 例如 `${xxx|isTrue:'foo':bar}`，当 `xxx` 变量为真，那么会返回 **字符串`'foo'`**，如果不为真，那么返回数据域中 **变量`bar`** 的值。

```schema
{
  "type": "page",
  "data": {
    "value1": true,
    "value2": false
  },
  "body": [
    {
        "type": "tpl",
        "tpl": "value1：${value1|isTrue:'是真':'是假'}" // 输出: value是真
    },
    {
        "type": "divider"
    },
    {
        "type": "tpl",
        "tpl": "value2：${value2|isTrue:'是真':'是假'}" // 输出: value是真
    }
  ]
}
```

##### 返回数据域中变量

参数中不添加引号，可以直接返回数据域中变量值

```schema
{
  "type": "page",
  "data": {
    "value1": true,
    "value2": false,
    "trueValue": "这个值是真的",
    "falseValue": "这个值是假的"
  },
  "body": [
    {
        "type": "tpl",
        "tpl": "value1：${value1|isTrue:trueValue:falseValue}" // 输出: value是真
    },
    {
        "type": "divider"
    },
    {
        "type": "tpl",
        "tpl": "value2：${value2|isTrue:trueValue:falseValue}" // 输出: value是真
    }
  ]
}
```

### isFalse

假值条件过滤器

##### 基本用法

```
${xxx | isFalse[:falseValue][:trueValue]
```

用法与 [isTrue 过滤器](#istrue) 相同，判断逻辑相反

### isMatch

模糊匹配条件过滤器

##### 基本用法

```
${xxx | isMatch[:matchParam][:trueValue][:falseValue]
```

- **matchParam**: 匹配关键字参数
  - 如果想模糊匹配特定字符串，那么参数需要在两边添加单引号或者双引号；
  - 如果想模糊匹配某个变量值，那么参数不需要添加引号。
- **trueValue**: 如果模糊匹配成功，即返回该值；
- **falseValue**: 如果模糊匹配失败，则返回该值。

```schema
{
  "type": "page",
  "data": {
    "text1": "Hello",
    "text2": "World"
  },
  "body": [
    {
        "type": "tpl",
        "tpl": "${text1|isMatch:'hello':'匹配':'不匹配'}" // 输出: 匹配
    },
    {
        "type": "divider"
    },
    {
        "type": "tpl",
        "tpl": "${text2|isMatch:'hello':'匹配':'不匹配'}" // 输出: 匹配
    }
  ]
}
```

##### 返回数据域中变量

参数中不添加引号，可以直接返回数据域中变量值

```schema
{
  "type": "page",
  "data": {
    "text1": "Hello",
    "text2": "World",
    "matchValue": "这个值匹配上了",
    "notmatchValue": "这个值没有匹配上"
  },
  "body": [
    {
        "type": "tpl",
        "tpl": "${text1|isMatch:'hello':matchValue:notmatchValue}" // 输出: 匹配
    },
    {
        "type": "divider"
    },
    {
        "type": "tpl",
        "tpl": "${text2|isMatch:'hello':matchValue:notmatchValue}" // 输出: 匹配
    }
  ]
}
```

### notMatch

##### 基本用法

```
${xxx | notMatch[:matchParam][:trueValue][:falseValue]
```

用法与 [isMatch](#isMatch) 相同，判断逻辑相反。

### isEquals

全等匹配过滤器

##### 基本用法

```
${xxx | isEquals[:equalsValue][:trueValue][:falseValue]
```

- **equalsValue**: 全等匹配关键字参数
  - 如果想判断等于特定字符串，那么参数需要在两边添加单引号或者双引号；
  - 如果想判断等于某个变量值，那么参数不需要添加引号。
- **trueValue**: 如果模糊匹配成功，即返回该值；
- **falseValue**: 如果模糊匹配失败，则返回该值。

```schema
{
  "type": "page",
  "data": {
    "text1": "Hello",
    "text2": "hello"
  },
  "body": [
    {
        "type": "tpl",
        "tpl": "${text1|isEquals:'Hello':'等于':'不等于'}" // 输出: 等于
    },
    {
        "type": "divider"
    },
    {
        "type": "tpl",
        "tpl": "${text2|isEquals:'Hello':'等于':'不等于'}" // 输出: 等于
    }
  ]
}
```

##### 返回数据域中变量

参数中不添加引号，可以直接返回数据域中变量值

```schema
{
  "type": "page",
  "data": {
    "text1": "Hello",
    "text2": "hello",
    "equalsValue": "这个值等于'Hello'",
    "notequalsValue": "这个值不等于'Hello'"
  },
  "body": [
    {
        "type": "tpl",
        "tpl": "${text1|isEquals:'Hello':equalsValue:notequalsValue}" // 输出: 等于
    },
    {
        "type": "divider"
    },
    {
        "type": "tpl",
        "tpl": "${text2|isEquals:'Hello':equalsValue:notequalsValue}" // 输出: 等于
    }
  ]
}
```

### notEquals

不全等匹配过滤器

##### 基本用法

```
${xxx | notEquals[:equalsValue][:trueValue][:falseValue]}
```

用法与 [isEquals](#isEquals) 相同，判断逻辑相反。

### map

数组操作，操作对象为数组，当目标对象不是数组或者 mapFn(filterName) 不存在时将无效。

##### 基本用法

```
${xxx | map[:filterName][:...args]}
```

```schema
{
  "type": "page",
  "body": {
    "type": "form",
    "mode": "horizontal",
    "api": {
      "method": "post",
      "url": "/api/mock2/form/saveForm",
      "data": {
        "test": "${combo2|pick:text|map:toInt|map:date:LLL:x}"
      }
    },
    "body": [
      {
        "type": "combo",
        "name": "combo2",
        "label": "Combo 多选展示",
        "multiple": true,
        "value": [
          {
            "text": "1586865590000"
          },
          {
            "text": "2696865590000"
          }
        ],
        "items": [
          {
            "name": "text",
            "type": "text"
          }
        ]
      }
    ]
  }
}
```

### filter

过滤数组，操作对象为数组，当目标对象不是数组时将无效。

##### 基本用法

```
${xxx | filter[:keys][:directive][:arg1]}
```

- **keys**: 参与过滤的字段集合
- **directive**: 用于过滤数组的指令，包含下面这几种

  - `isTrue` 目标值为真通过筛选。
  - `isFalse` 目标值为假时通过筛选。
  - `isExists` 目标值是否存在。
  - `match` 模糊匹配后面的参数。`${xxx|filter:a,b:match:keywords}` 表示 xxx 里面的成员，如果字段 a 或者 字段 b 模糊匹配 keywords 变量的值，则通过筛选。
  - `equals` 相对于模糊匹配，这个就相对精确匹配了，用法跟 `match` 一样。
  - `isIn` 目标值是否在一个范围内？`${xxx|filter:yyy:isIn:[a,b]}` xxx 数组内的 yyy 变量是否是字符串 `"a"` 或者 `"b"`，如果要取变量就是 `${xxx|filter:yyy:isIn:zzz}` xxx 数组内的 yyy 属性，必须在 zzz 变量这个数组内。
  - `notIn`目标值是否不在一个范围内，参考 `isIn`。

- **arg1**: 字符串或变量名

  比如: `${xxx|filter:readonly:isTrue}` 将 xxx 数组中 readonly 为 true 的成员提取出来。
  再来个例子：`${xxx|filter:a,b:match:keywords}` 将 xxx 数组中成员变量 a 或者 b 的值与环境中 keywords 的值相匹配的提取出来。如果不需要取变量，也可以写固定值如：`${xxx|filter:a,b:match:'123'}`

## 串联使用过滤器

使用单一的过滤器可能无法满足你的所有需求，幸运的是 amis 支持串联使用过滤器，而前一个过滤器的值会作为下一个过滤器的入参，进行下一步处理。语法如下:

```
${xxx|filter1|filter2|...}
```

##### 先拆分字符串，再获取第 n 个值

```schema
{
  "type": "page",
  "data": {
    "value":"a,b,c"
  },
  "body": {
    "type": "tpl",
    "tpl": "${value|split|first}" // 输出: a
  }
}
```

上例子中`${value|split|first}`，会经历下面几个步骤：

1. 会先执行`split`过滤器，将字符串`a,b,c`，拆分成数组`["a", "b", "c"]`；
2. 然后将该数据传给下一个过滤器`first`，执行该过滤器，获取数组第一个元素，为`"a"`
3. 输出`"a"`

## 自定义过滤器

amis npm 包里面暴露了 `registerFilter` 方法，通过它可以添加自己的过滤器逻辑。

> 注意方法名不要出现 - 号，比如 a-b，要改成 a_b

如：

```ts
import {registerFilter} from 'amis';

registerFilter('count', (input: string) =>
  typeof input === 'string' ? input.length : 0
);
```

注册后可以通过 `${xxx|count}` 来返回字符串的长度。

如果你的过滤器还要支持参数，可以参考这个例子。

```ts
import {registerFilter} from 'amis';

registerFilter('my_replace', (input: string, search: string, repalceWith) =>
  typeof input === 'string' ? input.replace(search, repalceWith) : input
);
```

用法为 `${xxxx|my_replace:aaaa:bbbb}`

### 在 JS SDK 中自定义过滤器

```javascript
let amisLib = amisRequire('amis');
amisLib.registerFilter('count', function (input) {
  return typeof input === 'string' ? input.length : 0;
});
```

---

### Zh CN Concepts Datascope And Datachain (`docs/zh-CN/concepts/datascope-and-datachain.md`)

---
title: 数据域与数据链
description:
type: 0
group: 💡 概念
menuName: 数据域与数据链
icon:
order: 10
---

## 基本的数据展示

我们再看之前的简单示例：

```json
{
  "type": "page",
  "body": "Hello World!"
}
```

目前我们只是在 `Page` 组件中渲染一串固定的文本，如何实现 **通过接口拉取想要的数据，并展示到 `Page` 组件的内容区** 呢？

## 添加初始化接口

```json
{
  "type": "page",
  "initApi": "/api/mock2/page/initData",
  "body": "date is ${date}"
}
```

这个 api 接口返回的数据结构如下：

```json
{
  "status": 0,
  "msg": "",
  "data": {
    "title": "Test Page Component",
    "date": "2017-10-13"
  }
}
```

渲染后页面效果：

```schema
{
  "type": "page",
  "initApi": "/api/mock2/page/initData",
  "body": "date is ${date}"
}
```

## 发生了什么?

我们可以看到，输出结果不变，但是我们这次渲染的是接口返回的数据：

1. 首先我们给 `Page` 组件配置了`initApi`属性，该属性会在组件初始化时，请求所该属性所配置的接口
2. 接口请求成功后，`Page` 会把接口返回的`data`内数据存到当前的数据域中
3. `Page` 在渲染 `body` 所配置的文本时，会解析文本内容，当解析到模板变量`${text}`时，amis 会把尝试在当前组件的数据域中获取`text`变量值，并替换掉`${text}`，最后渲染解析后的文本。

> 下一节我们会介绍[模板](./template)，`body`属性自身支持模板语法，amis 中支持模板语法的组件还有很多

## 数据域

前面我们提到了**数据域**这个概念，它是 amis 中最重要的概念之一。

还是通过最简单的示例进行讲解：

```json
{
  "type": "page",
  "body": "Hello ${text}"
}
```

上面的配置要做的很简单：使用 `Page` 组件，在内容区内渲染一段模板文字，其中`${text}`是**模板变量**，它会去到当前组件的数据域中，获取`text`变量值。

毫无疑问，`${text}`将会解析为空白文本，最终渲染的文本是 `Hello`

```schema
{
  "type": "page",
  "body": "Hello ${text}"
}
```

因为当前 `Page` 组件的数据域中是没有任何数据的，相比之前的示例，区别在于前面我们为 `Page` 组件配置了初始化接口，它会将接口返回的数据存入数据域中以供组件使用。

再观察下面这段配置：

```schema
{
  "data": {
    "text": "World!"
  },
  "type": "page",
  "body": "Hello ${text}"
}
```

再次查看渲染结果，顺利输出了 `Hello World!`

相信你可能已经猜到，**组件的`data`属性值是数据域的一种形式**，实际上当我们没有显式的配置数据域时，可以假想成这样：

```schema
{
  "data": {}, // 空的数据域
  "type": "page",
  "body": "Hello ${text}"
}
```

> 而前面我们知道 amis 的特性之一是基于组件树，因此自然数据域也会形成类似于树型结构，如何来处理这些数据域之间的联系呢，这就是我们马上要介绍到的 **[数据链](./datascope-and-datachain#%E6%95%B0%E6%8D%AE%E9%93%BE)**

## 数据链

相信通过上文，你已经基本掌握了 amis 中数据域的概念，接下来我们会介绍另一个重要概念：**数据链**。

**数据链**的特性是，当前组件在遇到获取变量的场景（例如模板渲染、展示表单数据、渲染列表等等）时：

1. 首先会先尝试在当前组件的数据域中寻找变量，当成功找到变量时，通过数据映射完成渲染，停止寻找过程；
2. 当在当前数据域中没有找到变量时，则向上寻找，在父组件的数据域中，重复步骤`1`和`2`；
3. 一直寻找，直到顶级节点，也就是`page`节点，寻找过程结束。
4. 但是如果 url 中有参数，还会继续向上查找这层，所以很多时候配置中可以直接 `${id}` 取地址栏参数。

> 为了方便讲解，我们这一章的例子统一使用的设置组件`data`属性的方式来初始化数据域，请记住，如果组件支持，你永远可以通过接口来进行数据域的初始化

继续来看这个例子：

```schema
{
  "type": "page",
  "data": {
    "name": "zhangsan",
    "age": 20
  },
  "body": [
    {
      "type": "tpl",
      "tpl": "my name is ${name}"
    },
    {
      "type": "service",
      "data": {
        "name": "lisi"
      },
      "body":  {
        "type": "tpl",
        "tpl": "my name is ${name}, I'm ${age} years old"
      }
    }
  ]
}
```

上面的配置项形成了如下的组件树和数据链：

组件树：

```
page
  ├─ tpl
  └─ service
       └─ tpl
```

数据链：

```json
{
  "name": "zhangsan",
  "age": 20,
  "__sub": {
    "name": "lisi"
  }
}
```

> `__sub` 字段只是为了方便理解。

首先，`page`组件下的`tpl`组件，在渲染`my name is ${name}`时，首先会在`page`的数据域中，尝试寻找`name`变量，在当前数据域中，`name`变量为`zhangsan`，因此寻找变量结束，通过数据映射渲染，输出：`my name is zhangsan`，渲染结束；

然后，`service`组件开始渲染，`service`组件内子组件`tpl`，它配置的模板字符串是：`my name is ${name}, I'm ${age} years old`，它会在`service`的数据域中，尝试寻找`name`和`age`变量。

由代码可以看出，`service`数据域中`name`变量为`lisi`，因此停止该变量的寻找，接下来寻找`age`变量。

很明显在`service`数据域中寻找`age`变量会失败，因此向上查找，尝试在`page`数据域中寻找`age`变量，找到为`20`，寻找变量结束，通过数据映射渲染，输出：`my name is lisi, I'm 20 years old`，渲染结束。

> **注意：** 当前例子中，对数据域中数据的获取使用的是 **\${xxx}** 模板语法，但是在不同的组件配置项中，获取数据的语法会有差异，我们会在后续的[模板](./template)和[表达式章节](./expression)中一一介绍。

### 具备数据域的组件

- App
- Page
- Cards
- Chart
- CRUD
- CRUD2
- Dialog
- Drawer
- List
- Form
- PaginationWrapper
- Service
- Wizard
- Combo
- InputArray
- Table
- Table2

有个特殊情况是 CRUD 中 filter，实际上是个 form，所以 CRUD 中有两层数据域，第一层是 CRUD 本身，同时查询条件表单中也有一层数据域。

### 常见误解

需要注意，只有少数几个容器组件会创建新的数据域，具体查看[具备数据域的组件](#具备数据域的组件)列表。

常见的错误写法是给容器组件加 data 属性，比如：

```schema
{
  "type": "page",
  "data": {
    "name": "zhangsan"
  },
  "body": [
    {
      "type": "tpl",
      "tpl": "my name is ${name}"
    },
    {
      "type": "container",
      "data": {
        "name": "lisi"
      },
      "body":  {
        "type": "tpl",
        "tpl": "my name is ${name}"
      }
    }
  ]
}
```

这样是不会生效的，正确的做法是使用 Service 包裹一层，如下所示

```schema
{
  "type": "page",
  "data": {
    "name": "zhangsan"
  },
  "body": [
    {
      "type": "tpl",
      "tpl": "my name is ${name}"
    },
    {
      "type": "service",
      "data": {
        "name": "lisi"
      },
      "body": {
        "type": "container",
        "body":  {
          "type": "tpl",
          "tpl": "my name is ${name}"
        }
      }
    }
  ]
}
```

## 初始化数据域

通过上面的介绍你可能发现，初始化数据域有两种方式：

### 1. 配置组件初始化接口

想要将自己的服务中的数据保存到某个组件的数据域中，最好的方式就是为当前组件配置初始化接口：

```json
{
  "type": "page",
  "initApi": "/api/initData",
  "body": "Hello ${text}"
}
```

接口必须按照下面的格式返回：

```json
{
  "status": 0,
  "msg": "",
  "data": {
    "text": "World!"
    ...其他字段
  }
}
```

**注意：**

1. **并不是所有组件都支持配置初始化接口来实现数据域初始化操作**，对于那些不支持配置初始化接口的组件来说，一般会使用 [**Service 组件**](../../components/service) 来辅助实现数据域初始化；
2. **`status`**、**`msg`** 和 **`data`** 字段为接口返回的必要字段；
3. `data`必须返回一个具有`key-value`结构的对象

```json
{
  "status": 0,
  "msg": "",
  "data": { // 正确
    "text": "World!"
  }
}

// 直接返回字符串或者数组都是无效的
{
  "status": 0,
  "msg": "",
  "data": "some string" // 错误，使用 key 包装
}
{
  "status": 0,
  "msg": "",
  "data": ["a", "b"] // 错误，使用 key 包装
}
```

> `api` 除了配置字符串格式以外，还可以配置复杂对象结构，更多详情查看[API 文档](../types/api)

### 2. 显式配置 data 属性值

另一种初始化当前数据域的方式是显式的设置组件的`data`属性值：

```schema
{
  "data": {
    "text": "World!",
    "name": "amis"
  },
  "type": "page",
  "body": "Hello ${text}, my name is ${name}."
}
```

### 同时配置

在同时配置 **初始化接口** 和 **`data`属性** 时，数据域将会合并`data`属性值和初始化接口返回的数据

## 更新数据域

部分组件的某些交互或行为会对当前组件的数据域进行更新：

```schema
{
  "type": "page",
  "body": {
    "type": "form",
    "api": "/api/mock2/form/saveForm",
    "body": [
      {
        "type": "input-text",
        "name": "name",
        "label": "姓名："
      },
      {
        "type": "input-text",
        "name": "age",
        "label": "年龄："
      },
      {
        "type": "static-tpl",
        "tpl": "生成的id为：${id}"
      }
    ]
  }
}
```

`/api/saveForm`接口会保存当前表单提交的数据，并返回后端服务生成的`id`，并返回到前端，格式如下;

```json
{
  "status": 0,
  "msg": "保存成功",
  "data": {
    "id": 1
  }
}
```

这时 amis 将会把`data`数据与当前`form`组件的数据域进行**merge**，`form`组件中的`static-tpl`组件会根据更新后的数据域，显示`id`为`1`。

> 具有类似特征的组件还有`Formula`等

## 更新数据链

通常顶层数据域数据更新，孩子中具备数据域的组件都会更新，如果不更新会拿不到最新的值。从功能来看这个更新代价其实是很大的，有性能损耗，比如我在顶层更新了个变量 `name`，所有的孩子都会重新刷新一遍。
目前 amis 中，具备数据域的组件，默认会检测两层节点的数据是否发生变化（上层数据域和上上层数据域），来决定当前层的数据要不要更新。存在两个问题：

1. 当前组件也许并不关心上层数据是否变化，没必要进行这些刷新操作
2. 当前组件关心上上层的数据变化，但是在此拿不到最新的。（比如：放在 service 中的 crud，crud 中 filter 用了 service 的接口返回数据，但是拿不到最新的）

amis 从 3.2.0 版本开始针对[具备数据域的组件](#具备数据域的组件)新增了 `trackExpression` 属性，用来主动配置当前组件需要关心的上层数据。

针对以上问题，则可以通过这样配置来解决

1.  `trackExpression` 配置成 `"none"` 也就是说不追踪任何数据。
2.  `trackExpression` 配置成 `"${xxxVariable}"` 这样 xxxVariable 变化了更新当前组件的数据链。

关于 `trackExpression` 的语法，请查看表达式篇章，可以监听多个变量比如: `"${xxx1},${xxx2}"`，还可以写表达式如 `"${ xxx ? xxx : yyy}"`。

amis 内部是通过运算这个表达式的结果来判断。所以表达式中千万不要用随机函数，或者用当前时间等，否则每次都会更新数据链。另外如果变量是数组，或者对象，会转成统一的字符串 `[object Array]` 或者 `[object Object]` 这个其实会影响检测的，所以建议转成 json 字符串如。 `${xxxObject | json}`。还有就是既然是监控上层数据，表达式中不要写当前层数据变量，是取不到的。

```schema
{
  "data": {
    "name": "amis"
  },
  "type": "page",
  "body": [
    { "label": "请修改输入框", "type": "input-text", "name": "name"},
    {
      "type": "switch",
      "label": "同步更新",
      "name": "syncSwitch"
    },
    {
      "type": "crud",
      "filter": {
        "trackExpression": "${syncSwitch ? name : ''}",
        "body": [


          "my name is ${name}"
        ]
      }
    }
  ]
}
```

## URL 参数

url 中的参数会进入顶层数据域，比如下面的例子，可以点击[这里](./datascope-and-datachain?word=myquery#url-参数)看效果。

```schema
{
  "type": "page",
  "body": "${word}"
}
```

## 隐藏数据

数据中还有以下字段不会被枚举到，但是可以读取：

- `__prev` 修改前的值
- `__changeReason` 修改原因
- `__changeReason.type` 修改原因类型
  - `input` 用户输入
  - `api` api 接口返回触发
  - `formula` 公式计算触发
  - `hide` 隐藏属性变化触发
  - `init` 表单项初始化触发
  - `action` 事件动作触发
- `__super` 数据链的上一级

> `__changeReason` 字段在 amis 6.9.0 版本开始支持

```schema
{
  "data": {
    "name": "amis"
  },
  "type": "form",
  id: "form_data",
  "actions": [
    {
      type: "button",
      label: "接口获取",
      actionType: "ajax",
      api: {
        "method": "get",
        url: "/api/mock2/form/saveForm",
        mockResponse: {
          status: 200,
          data: {
            name: "amis-demo"
          }
        }
      }
    },

    {
      type: "button",
      label: "设置值",
      onEvent: {
        click: {
          actions: [
            {
              "actionType": "setValue",
              "componentId": "form_data",
              "args": {
                "value": {
                  "name": "amis-demo2"
                }
              }
            }
          ]
        }
      }
    },
  ],
  "body": [
    {
      type: "input-text",
      name: "name",
      label: "姓名"
    },
    {
      type: "tpl",
      tpl: "当前值：${name}<br />修改前的值：${__prev.name}<br />变化原因：${__changeReason|json}"
    }
  ]
}
```

---

### Zh CN Concepts Event Action (`docs/zh-CN/concepts/event-action.md`)

---
title: 事件动作
description: 事件动作
type: 0
group: 💡 概念
menuName: 事件动作
icon:
order: 9
---

> 1.7.0 及以上版本

上一节我们介绍了如何实现联动，是比较基础和局限的，而事件动作是更简单、更灵活、更高级的用法，可以解决复杂的 UI 交互场景，支持渲染器事件监听和响应设计，无需关心组件层级关系。例如：

- http 请求：发送 http 请求
- 弹窗提示：执行弹窗、抽屉打开和 toast 提示
- 页面跳转：页面链接跳转
- 浏览器相关：回退、前进、后退、刷新
- 刷新组件：联动刷新表单数据，即数据重新加载
- 组件状态：控制指定组件的显示/隐藏、启用/禁用、展示态/编辑态
- 组件特性动作：执行指定组件的专有动作，例如执行表单的提交动作
- 组件数据：更新指定组件的数据域
- 广播：多个组件监听同一个事件做出不同响应
- JS 脚本：通过编写 JS 代码片段实现所需逻辑，同时支持 JS 代码内执行动作
- 逻辑编排：条件、循环、排他、并行

## 基本使用

### onEvent

通过`onEvent`属性实现渲染器事件与响应动作的绑定。`onEvent`内配置事件和动作映射关系，`actions`是事件对应的响应动作的集合。

```json
{
  "type": "button",
  "label": "尝试点击、鼠标移入/移出",
  "level": "primary",
  "onEvent": {
    "click": { // 监听点击事件
      "actions": [ // 执行的动作列表
        {
          "actionType": "toast", // 执行toast提示动作
          "args": { // 动作参数
            "msgType": "info",
            "msg": "派发点击事件"
          }
        }
      ]
    },
    "mouseenter": {{ // 监听鼠标移入事件
      "actions": [
        {
          "actionType": "toast",
          "args": {
            "msgType": "info",
            "msg": "派发鼠标移入事件"
          }
        }
      ]
    },
    "mouseleave": {{ // 监听鼠标移出事件
      "actions": [
        {
          "actionType": "toast",
          "args": {
            "msgType": "info",
            "msg": "派发鼠标移出事件"
          }
        }
      ]
    }
  }
}
```

```schema
{
  "type": "page",
  "body": [
    {
      "type": "button",
      "label": "尝试点击、鼠标移入/移出",
      "level": "primary",
      "onEvent": {
        "click": {
          "actions": [
            {
              "actionType": "toast",
              "args": {
                "msgType": "info",
                "msg": "派发点击事件"
              }
            }
          ]
        },
        "mouseenter": {
          "actions": [
            {
              "actionType": "toast",
              "args": {
                "msgType": "info",
                "msg": "派发鼠标移入事件"
              }
            }
          ]
        },
        "mouseleave": {
          "actions": [
            {
              "actionType": "toast",
              "args": {
                "msgType": "info",
                "msg": "派发鼠标移出事件"
              }
            }
          ]
        }
      }
    }
  ]
}
```

### 上下文

执行动作时，可以通过`${event.data}`获取事件对象的数据、通过`${__rendererData}`获取组件当前数据域，例如：

```
/* Detailed source-code truncated for AI context efficiency. */
```

### 运行日志

可以在浏览器控制台查看运行日志，类似如下

```
run action ajax
  [ajax] action args, data {api: {…}, messages: {…}}
  [ajax] action end event {context: {…}, type: 'click', prevented: false, stoped: false, preventDefault: ƒ, …}
```

代表运行了 ajax 动作，第二行是传递的参数和数据，第三行是执行完动作之后的 `event` 值，可以用做后续动作的参数。

## 分类

事件包含`渲染器事件`和`广播事件`。

- 渲染器事件，由具体的渲染器组件提供，每个渲染器组件暴露的事件可以查看具体的[组件文档的事件表](../../components/page#事件表)；
- 广播事件，即自定义事件，可以自定义派发的事件名称`eventName`，其他渲染器可以监听该自定义事件并配置响应动作。

动作包含`通用动作`、`组件动作`、`广播动作`、`自定义动作`，可以通过配置`actionType`来指定具体执行什么动作。

## 发送 http 请求

通过配置`actionType: 'ajax'`实现 http 请求发送，该动作需实现 `env.fetcher` 请求器。

```schema
{
  type: 'page',
  data: {
    name: 'lll'
  },
  body: [
    {
      type: 'button',
      id: 'b_001',
      label: '发送 Ajax 请求',
      level: 'primary',
      "confirmText": "确认要发出这个请求？",
      onEvent: {
        click: {
          actions: [
            {
              actionType: 'ajax',
              api: {
                url: 'https://3xsw4ap8wah59.cfc-execute.bj.baidubce.com/api/amis-mock/mock2/form/saveForm?name=${name}',
                method: 'post',
                responseData: {
                  "resId": "${id}",
                },
                messages: {
                  success: '成功了！欧耶',
                  failed: '失败了呢。。'
                },
              },
              data: {
                age: 18
              }
            },
            {
              actionType: 'toast',
              expression: '${event.data.responseResult.responseStatus === 0}',
              args: {
                msg: '${event.data.responseResult|json}'
              }
            }
          ]
        }
      }
    }
  ]
}
```

### 静默模式

当配置`silent: true`时，请求完成后不会弹出提示信息。

```schema
{
  type: 'page',
  data: {
    name: 'lll'
  },
  body: [
    {
      type: 'button',
      id: 'b_001',
      label: '发送 Ajax 请求（静默模式）',
      level: 'primary',
      "confirmText": "确认要发出这个请求？",
      className: 'm',
      onEvent: {
        click: {
          actions: [
            {
              actionType: 'ajax',
              api: {
                url: 'https://3xsw4ap8wah59.cfc-execute.bj.baidubce.com/api/amis-mock/initData',
                method: 'post',
                messages: {
                  success: '成功了！欧耶',
                  failed: '失败了呢。。'
                },
                silent: true
              },
              data: {
                age: 18
              }
            },
            {
              actionType: 'toast',
              expression: '${event.data.responseResult.responseStatus === 0}',
              args: {
                msg: '${event.data.responseResult|json}'
              }
            }
          ]
        }
      }
    }
  ]
}
```

### 可读取的数据

请求配置中可读取的数据包含事件源所在数据域和动作执行产生的数据。可以通过`api.data`配置数据映射来读取所需数据。例如：

- 取所在数据域的数据：通过`"name": "${name}", "email": "${email}"`来映射表单校验数据（只适用于事件源在表单内的情况）
- 取动作产生的数据：通过`"name": "${event.data.validateResult.payload.name}", "email": "${event.data.validateResult.payload.email}"`来映射表单校验数据，这种是获取前面表单校验动作的校验结果数据。通过`"&": "${event.data.validateResult.payload}"`展开表单校验数据，结果相同，这是一个数据映射小技巧

```
/* Detailed source-code truncated for AI context efficiency. */
```

**动作属性**

| 属性名   | 类型                                | 默认值 | 说明                      |
| -------- | ----------------------------------- | ------ | ------------------------- |
| api      | [API](../../../docs/types/api)      | -      | 接口配置                  |
| options  | `object`                            | -      | 其他配置                  |
| messages | `{success: string, failed: string}` | -      | 请求成功/失败后的提示信息 |

**其他属性**

| 属性名    | 类型     | 默认值 | 说明                                                                          |
| --------- | -------- | ------ | ----------------------------------------------------------------------------- |
| outputVar | `string` | -      | 请求响应结果缓存在`${event.data.responseResult}`或`${event.data.{outputVar}}` |

请求响应结果的结构如下：

```json
{
  // 状态码
  "responseStatus": 0,
  // 响应数据
  "responseData": {
    "xxx": "xxx"
  },
  // 响应消息
  "responseMsg": "ok"
}
```

## 弹窗

### 打开弹窗（模态）

通过配置`actionType: 'dialog'`实现 Dialog 弹窗。

```
/* Detailed source-code truncated for AI context efficiency. */
```

**动作属性**

| 属性名        | 类型                    | 默认值 | 说明                                                                                                 |
| ------------- | ----------------------- | ------ | ---------------------------------------------------------------------------------------------------- |
| dialog        | `string`/`DialogObject` | -      | 指定弹框内容，格式可参考[Dialog](../../components/dialog)                                            |
| waitForAction | `boolean`               | -      | 是否等待弹窗响应，开启后将等待弹窗操作                                                               |
| outputVar     | `string`                | -      | 输出数据变量名, 输出数据格式为 `{confirmed: boolean; value: any[]}`，当 `waitForAction` 开启时才有用 |

### 关闭弹窗（模态）

通过配置`actionType: 'closeDialog'`实现关闭当前弹窗；附加配置`componentId`可以实现关闭指定弹窗。

```
/* Detailed source-code truncated for AI context efficiency. */
```

**其他属性**

| 属性名      | 类型     | 默认值 | 说明            |
| ----------- | -------- | ------ | --------------- |
| componentId | `string` | -      | 指定弹框组件 id |

### 打开抽屉（模态）

通过配置`actionType: 'drawer'`实现 Drawer 抽屉打开。

```schema
{
  type: 'page',
  body: [
    {
      type: 'button',
      id: 'b_004',
      level: 'primary',
      label: '打开抽屉（模态）',
      onEvent: {
        click: {
          actions: [
            {
              actionType: 'drawer',
              drawer: {
                type: 'drawer',
                title: '模态抽屉',
                body: [
                  {
                    type: 'tpl',
                    tpl: '<p>对，你打开了模态抽屉</p>',
                    inline: false
                  }
                ],
                onEvent: {
                  confirm: {
                    actions: [
                      {
                        actionType: 'toast',
                        args: {
                          msg: 'confirm'
                        }
                      }
                    ]
                  },
                  cancel: {
                    actions: [
                      {
                        actionType: 'toast',
                        args: {
                          msg: 'cancel'
                        }
                      }
                    ]
                  }
                }
              }
            }
          ]
        }
      }
    }
  ]
}
```

**动作属性**

| 属性名        | 类型                    | 默认值 | 说明                                                                                                 |
| ------------- | ----------------------- | ------ | ---------------------------------------------------------------------------------------------------- |
| drawer        | `string`/`DrawerObject` | -      | 指定弹框内容，格式可参考[Drawer](../../components/drawer)                                            |
| waitForAction | `boolean`               | -      | 是否等待弹窗响应，开启后将等待弹窗操作                                                               |
| outputVar     | `string`                | -      | 输出数据变量名, 输出数据格式为 `{confirmed: boolean; value: any[]}`，当 `waitForAction` 开启时才有用 |

### 关闭抽屉（模态）

通过配置`actionType: 'closeDrawer'`实现关闭当前抽屉；附加配置`componentId`可以实现关闭指定抽屉。

```
/* Detailed source-code truncated for AI context efficiency. */
```

**其他属性**

| 属性名      | 类型     | 默认值 | 说明            |
| ----------- | -------- | ------ | --------------- |
| componentId | `string` | -      | 指定抽屉组件 id |

### 打开确认弹窗

通过配置`actionType: 'confirmDialog'`打开确认对话框。确认对话框弹出后，如果选择取消操作，将不会执行该动作后面的动作。如下面的例子，点击确认之后将弹出`toast`提示，点击取消则不会提示。

**普通文本内容**

动作需要实现 env.confirm: (msg: string, title?: string) => boolean | Promise&lt;boolean&gt;。

```schema
{
  type: 'page',
  data: {
    title: '操作确认',
    msg: '要删除它吗？'
  },
  body: [
    {
      type: 'button',
      label: '确认对话框（模态）',
      level: 'primary',
      onEvent: {
        click: {
          actions: [
            {
              actionType: 'confirmDialog',
              dialog: {
                title: '${title}',
                msg: '<span style="color:red">${msg}</span>'
              }
            },
            {
              actionType: 'toast',
              args: {
                msg: '确认ok啦！'
              }
            }
          ]
        }
      }
    }
  ]
}
```

**自定义弹窗内容**

可以通过`body`像配置弹窗一样配置确认弹窗的内容。

```
/* Detailed source-code truncated for AI context efficiency. */
```

**动作属性**

| 属性名 | 类型                          | 默认值 | 说明                                                                |
| ------ | ----------------------------- | ------ | ------------------------------------------------------------------- |
| dialog | {msg:`string`}/`DialogObject` | -      | 指定弹框内容。自定义弹窗内容可参考[Dialog](../../components/dialog) |

### 提示对话框

通过配置`actionType: 'alert'`打开提示对话框，该对话框只有确认按钮。该动作需要实现 env.alert: (msg: string) => void。

```schema
{
  type: 'page',
  data: {
    msg: '去吃饭了'
  },
  body: [
    {
      type: 'button',
      label: '提示对话框（模态）',
      level: 'primary',
      onEvent: {
        click: {
          actions: [
            {
              actionType: 'alert',
              dialog: {
                title: '提示',
                msg: '<a href="http://www.baidu.com" target="_blank">${msg}~</a>'
              }
            }
          ]
        }
      }
    }
  ]
}
```

**动作属性**

| 属性名 | 类型                             | 默认值                       | 说明       |
| ------ | -------------------------------- | ---------------------------- | ---------- |
| dialog | {title:`string`<br>msg:`string`} | {title: '系统提示', msg: ''} | 对话框配置 |

### toast 提示

通过配置`actionType: 'toast'`实现弹出 toast 提示，该动作需实现 env.notify(type: ToastLevel, msg: string, conf?: ToastConf) => void 方法。

```
/* Detailed source-code truncated for AI context efficiency. */
```

**动作属性（args）**

> `< 1.8.0 及以下版本`，以下属性与 args 同级。

| 属性名      | 类型      | 默认值                                  | 说明                                                                                             |
| ----------- | --------- | --------------------------------------- | ------------------------------------------------------------------------------------------------ |
| msgType     | `string`  | `"info"`                                | 消息类型 `info\|success\|error\|warning`                                                         |
| msg         | `string`  | -                                       | 消息内容                                                                                         |
| position    | `string`  | `top-center（移动端为center）`          | 提示显示位置 `top-right\|top-center\|top-left\|bottom-center\|bottom-left\|bottom-right\|center` |
| closeButton | `boolean` | `false`                                 | 是否展示关闭按钮                                                                                 |
| showIcon    | `boolean` | `true`                                  | 是否展示图标                                                                                     |
| timeout     | `number`  | `5000（error类型为6000，移动端为3000）` | 持续时间                                                                                         |

## 跳转链接

通过配置`actionType: 'url'`或`actionType: 'link'`实现链接跳转，该动作需实现 env.jumpTo(to: string, action?: any) => void 方法。

### 打开页面

```schema
{
  type: 'page',
  data: {
    myname: 'lvxj',
    myjon: 'player'
  },
  body: [
    {
      type: 'button',
      label: '百度一下',
      level: 'primary',
      className: 'ml-2',
      onEvent: {
        click: {
          actions: [
            {
              actionType: 'url',
              args: {
                url: 'http://www.baidu.com',
                blank: true,
                params: {
                  name: 'jack',
                  jon: '${myjon}'
                },
                name: '${myname}',
                age: 18
              }
            }
          ]
        }
      }
    }
  ]
}
```

**动作属性（args）**

> `< 1.8.0 及以下版本`，以下属性与 args 同级。

| 属性名 | 类型      | 默认值  | 说明                                                       |
| ------ | --------- | ------- | ---------------------------------------------------------- |
| url    | `string`  | -       | 按钮点击后，会打开指定页面。可用 `${xxx}` 取值             |
| blank  | `boolean` | `false` | 如果为 `true` 将在新 tab 页面打开                          |
| params | `object`  | -       | 页面参数`{key:value}`，支持数据映射，`> 1.10.0 及以上版本` |

### 打开单页

```schema
{
  type: 'page',
  body: [
    {
      type: 'button',
      label: '跳转至「表达式」',
      level: 'primary',
      className: 'ml-2',
      onEvent: {
        click: {
          actions: [
            {
              actionType: 'link',
              args: {
                link: './expression'
              }
            }
          ]
        }
      }
    }
  ]
}
```

**动作属性（args）**

> `< 1.8.0 及以下版本`，以下属性与 args 同级。

| 属性名     | 类型     | 默认值 | 说明                                                                                                                          |
| ---------- | -------- | ------ | ----------------------------------------------------------------------------------------------------------------------------- |
| link       | `string` | `link` | 用来指定跳转地址，跟 url 不同的是，这是单页跳转方式，不会渲染浏览器，请指定 amis 平台内的页面。可用 `${xxx}` 取值             |
| params     | `object` | -      | 页面参数`{key:value}`，支持数据映射，`> 1.9.0 及以上版本`                                                                     |
| targetType | `string` | `page` | 默认为内容区打开`page`，可设置为新窗口打开`blank`，当前页签打开`self`，`blank\|self` 方式会重新渲染浏览器`> 6.1.0 及以上版本` |

## 浏览器

### 浏览器回退

> 1.8.0 及以上版本

通过配置`actionType: 'goBack'`实现页面回退。

```schema
{
  type: 'page',
  body: [
    {
      type: 'button',
      label: '回退',
      level: 'primary',
      className: 'ml-2',
      onEvent: {
        click: {
          actions: [
            {
              actionType: 'goBack'
            }
          ]
        }
      }
    }
  ]
}
```

### 前进/后退到指定页面

> 1.8.0 及以上版本

通过配置`actionType: 'goPage'`实现浏览器页面的前进/后退。只有当历史记录中存在目标页面时才会生效。

```schema
{
  type: 'page',
  body: [
    {
      type: 'button',
      label: '后退到上上个页面',
      level: 'primary',
      className: 'ml-2',
      onEvent: {
        click: {
          actions: [
            {
              actionType: 'goPage',
              args: {
                delta: -2
              }
            }
          ]
        }
      }
    }
  ]
}
```

**动作属性（args）**

> `< 1.8.0 及以下版本`，以下属性与 args 同级。

| 属性名 | 类型     | 默认值 | 说明 |
| ------ | -------- | ------ | ---- |
| delta  | `string` | `0`    | 位置 |

### 浏览器刷新

> 1.8.0 及以上版本

通过配置`actionType: 'refresh'`实现浏览器刷新。

```schema
{
  type: 'page',
  body: [
    {
      type: 'button',
      label: '刷新页面',
      level: 'primary',
      className: 'ml-2',
      onEvent: {
        click: {
          actions: [
            {
              actionType: 'refresh'
            }
          ]
        }
      }
    }
  ]
}
```

## 复制

通过配置`actionType: 'copy'`和复制属性实现文本的复制操作，该动作需实现 env.copy(contents: string, options?: any) => void 方法。

```schema
{
  type: 'page',
  body: [
    {
      type: 'button',
      label: '复制一段文本',
      level: 'primary',
      className: 'mr-2',
      onEvent: {
        click: {
          actions: [
            {
              actionType: 'copy',
              args: {
                content: 'http://www.baidu.com'
              }
            }
          ]
        }
      }
    },
    {
      type: 'button',
      label: '复制一段富文本',
      level: 'primary',
      onEvent: {
        click: {
          actions: [
            {
              actionType: 'copy',
              args: {
                copyFormat: 'text/html',
                content: "<a href='http://www.baidu.com'>link</a> <b>bold</b>"
              }
            }
          ]
        }
      }
    }
  ]
}
```

**动作属性（args）**

> `< 1.8.0 及以下版本`，以下属性与 args 同级。

| 属性名     | 类型                                 | 默认值 | 说明                               |
| ---------- | ------------------------------------ | ------ | ---------------------------------- |
| copyFormat | `string`                             | -      | 复制格式                           |
| content    | [模板](../../docs/concepts/template) | -      | 指定复制的内容。可用 `${xxx}` 取值 |

## 打印

> 6.2.0 及以后版本

打印页面中的某个组件，对应的组件需要配置 `id`，如果要打印多个，可以使用 `"ids": ["x", "y"]` 来打印多个组件，只支持主要是容器类组件 `crud`、`crud2`、`form`、`table`、`wrapper`、`container`、`flex`、`grid`、`grid2d`、`tableview`

> breaking：在 6.2.0 版本中配置是 testid，但这个配置会导致性能问题，所以新版使用 id 作为标识。

```schema
{
  type: 'page',
  body: [
    {
      type: 'button',
      label: '打印',
      level: 'primary',
      className: 'mr-2',
      onEvent: {
        click: {
          actions: [
            {
              actionType: 'print',
              args: {
                id: 'mycrud'
              }
            }
          ]
        }
      }
    },
    {
      "type": "crud",
      "api": "/api/mock2/sample",
      "id": "mycrud",
      "syncLocation": false,
      "columns": [
        {
          "name": "id",
          "label": "ID"
        },
        {
          "name": "engine",
          "label": "Rendering engine"
        },
        {
          "name": "browser",
          "label": "Browser"
        },
        {
          "name": "platform",
          "label": "Platform(s)"
        },
        {
          "name": "version",
          "label": "Engine version"
        },
        {
          "name": "grade",
          "label": "CSS grade"
        }
      ]
    }
  ]
}
```

| 属性名  | 类型       | 默认值 | 说明              |
| ------- | ---------- | ------ | ----------------- |
| testid  | `string`   |        | 组件的 testid     |
| testids | `string[]` | -      | 多个组件的 testid |

## 发送邮件

通过配置`actionType: 'email'`和邮件属性实现发送邮件操作。

```schema
{
  type: 'page',
  body: [
    {
      type: 'button',
      label: '发送邮件',
      level: 'primary',
      onEvent: {
        click: {
          actions: [
            {
              actionType: 'email',
              args: {
                to: 'amis@baidu.com',
                cc: 'baidu@baidu.com',
                subject: '这是邮件主题',
                body: '这是邮件正文'
              }
            }
          ]
        }
      }
    }
  ]
}
```

**动作属性（args）**

> `< 1.8.0 及以下版本`，以下属性与 args 同级。

| 属性名  | 类型     | 默认值 | 说明                           |
| ------- | -------- | ------ | ------------------------------ |
| to      | `string` | -      | 收件人邮箱，可用 ${xxx} 取值   |
| cc      | `string` | -      | 抄送邮箱，可用 ${xxx} 取值     |
| bcc     | `string` | -      | 匿名抄送邮箱，可用 ${xxx} 取值 |
| subject | `string` | -      | 邮件主题，可用 ${xxx} 取值     |
| body    | `string` | -      | 邮件正文，可用 ${xxx} 取值     |

## 更新事件上下文数据

> 6.3.0 及以上版本

修改 `event.data` 对象中的数据，修改后，后续的动作中可以引用，及时生效，不像更新组件上下文数据是个异步操作。可以用来临时存储数据。

```schema
{
  type: 'page',
  title: '获取页面标题并弹出',
  body: [
    {
      type: 'button',
      className: 'ml-2',
      label: 'toast 页面标题',
      level: 'primary',
      onEvent: {
        click: {
          actions: [
            {
              actionType: 'setEventData',
              args: {
                key: 'title',
                value: '页面标题：${window:document[title]}'
              }
            },
            {
              actionType: 'toast',
              args: {
                msg: '${title}'
              }
            },
          ]
        }
      }
    }
  ]
}
```

## 等待

> 6.3.0 及以上版本

通过配置`actionType: 'wait'`，等待指定时间（`args.time` 毫秒数）后执行后续动作。

```schema
{
  type: 'page',
  title: '3 秒后 toast 页面标题',
  body: [
    {
      type: 'button',
      className: 'ml-2',
      label: 'toast 页面标题',
      level: 'primary',
      onEvent: {
        click: {
          actions: [
            {
              actionType: 'wait',
              args: {
                time: 3000
              }
            },
            {
              actionType: 'setEventData',
              args: {
                key: 'title',
                value: '页面标题：${window:document[title]}'
              }
            },
            {
              actionType: 'toast',
              args: {
                msg: '${title}'
              }
            },
          ]
        }
      }
    }
  ]
}
```

**动作属性（args）**

> `< 1.8.0 及以下版本`，以下属性与 args 同级。

| 属性名 | 类型     | 默认值 | 说明                 |
| ------ | -------- | ------ | -------------------- |
| time   | `number` | -      | 等待时间，单位是毫秒 |

## 自定义 JS

通过配置`actionType: 'custom'`实现自定义 JS。JS 中可以访问以下对象和方法：

- context，渲染器上下文
- doAction() 动作执行方法，用于调用任何 actionType 指定的动作
- event，事件对象，可以调用 setData()、stopPropagation()、preventDefault()分别实现事件上下文设置、动作干预、事件干预，可以通过 event.data 获取事件上下文

自定义函数签名： `script:(context,doAction,event)=>{}`

```schema
{
  type: 'page',
  body: [
    {
      type: 'button',
      label: '发送一个 http 请求',
      level: 'primary',
      onEvent: {
        click: {
          actions: [
            {
              actionType: 'custom',
              script:
                "doAction({actionType: 'ajax', args: {api: '/api/mock2/form/saveForm'}});\n //event.stopPropagation();"
            }
          ]
        }
      }
    }
  ]
}
```

**动作属性**

| 属性名 | 类型                | 默认值 | 说明                                                                                                                                            |
| ------ | ------------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| script | `string`/`function` | -      | 自定义 JS 脚本代码，代码内可以通过调用`doAction`执行任何[动作](../../docs/concepts/event-action#动作) ，通过事件对象`event`可以实现事件动作干预 |

### 支持异步

> 2.0.3 及以上版本

- 方式一：通过返回 Promise 实例的方式

```schema
{
  type: 'page',
  body: [
    {
      "type": "form",
      "title": "表单",
      "body": [
        {
          "label": "编号",
          "type": "input-text",
          "name": "pId",
          "id": "u:e47e2c8e6be8",
          "mode": "horizontal",
          "addOn": {
            "label": "自动获取",
            "type": "button",
            "onEvent": {
              "click": {
                "actions": [
                  {
                    "componentId": "u:52cd013e120f",
                    "actionType": "disabled"
                  },
                  {
                    "script": "return new Promise((resolve, reject) => {setTimeout(() => {event.setData({...event.data, pId: '01027359'});resolve();}, 3000)})",
                    "actionType": "custom"
                  },
                  {
                    "componentId": "u:e47e2c8e6be8",
                    "args": {
                      "value": "${pId}"
                    },
                    "actionType": "setValue"
                  },
                  {
                    "componentId": "u:52cd013e120f",
                    "actionType": "enabled"
                  }
                ],
                "weight": 0
              }
            },
            "id": "u:52cd013e120f"
          }
        }
      ],
      "apiFromAPICenter": false,
      "id": "u:76203156676b"
    }
  ]
}
```

- 方式二：通过返回 Thunk 的方式

```schema
{
  type: 'page',
  body: [
    {
      "type": "form",
      "title": "表单",
      "body": [
        {
          "label": "编号",
          "type": "input-text",
          "name": "pId",
          "id": "u:e47e2c8e6be7",
          "mode": "horizontal",
          "addOn": {
            "label": "自动获取",
            "type": "button",
            "onEvent": {
              "click": {
                "actions": [
                  {
                    "componentId": "u:52cd013e120e",
                    "actionType": "disabled"
                  },
                  {
                    "script": "return (callback) => { setTimeout(() => {event.setData({...event.data, pId: '01027359' });callback();}, 3000) };",
                    "actionType": "custom"
                  },
                  {
                    "componentId": "u:e47e2c8e6be7",
                    "args": {
                      "value": "${pId}"
                    },
                    "actionType": "setValue"
                  },
                  {
                    "componentId": "u:52cd013e120e",
                    "actionType": "enabled"
                  }
                ],
                "weight": 0
              }
            },
            "id": "u:52cd013e120e"
          }
        }
      ],
      "apiFromAPICenter": false,
      "id": "u:76203156676a"
    }
  ]
}
```

### 存储数据

有时在执行自定义 JS 的时候，希望该过程中产生的数据可以分享给后面的动作使用，此时可以通过`event.setData()`来实现事件上下文的设置，这样后面动作都可以通过事件上下文来获取共享的数据。

> 注意：直接调用`event.setData()`将修改事件的原有上下文，如果不希望覆盖可以通过`event.setData({...event.data, ...{xxx: xxx}})`来进行数据的合并。

## 触发指定组件动作

通过配置`componentId`或`componentName`来触发指定组件的动作（不配置将调用当前组件自己的动作），组件动作配置通过`args`传入`(> 1.9.0 及以上版本)`，动作参数请查看对应的组件的[动作表](../../components/form/index#动作表)，更多示例请查看[组件事件动作示例](../../../examples/event/form)。

### 更新组件数据

> 1.8.0 及以上版本

更新数据即更新指定组件数据域中的数据（data），通过配置`actionType: 'setValue'`实现组件`数据域变量更新`，通过它可以实现`组件间联动更新`、`数据回填`，更多示例请查看[更新数据示例](../../../examples/action/setdata/form)。

**注意事项**

- 这个动作是异步的，所以不能直接通过`${xxx}`来获取更新后的数据，如果需要请更新事件上下文数据，然后通过`${event.data.xxx}`来获取。
- 数据类型支持范围：`基础类型`、`对象类型`、`数组类型`，数据类型取决于目标组件所需数据值类型
- 目标组件支持范围：`form`、`dialog`、`drawer`、`wizard`、`service`、`page`、`app`、`chart`，以及数据`输入类`组件
- < 2.3.2 及以下版本，虽然更新数据可以实现对组件数据域的更新，但如果更新数据动作的数据值来自前面的异步动作（例如 发送 http 请求、自定义 JS（异步）），则后面的动作只能通过事件变量`${event.data.xxx}`来获取异步动作产生的数据，无法通过当前数据域`${xxx}`直接获取更新后的数据。
- 它的值通常都是对象形式，比如 form 传递的值应该是类似 `{"user": "amis"}`，这时就会更新表单里的 `user` 字段值为 `amis`

```schema
{
  type: 'page',
  title: '更新表单数据',
  data: {
    globalData: {
      myrole: '法官',
      mymsg: '该吃饭了!'
    }
  },
  body: [
    {
      type: 'button',
      label: '更新',
      level: 'primary',
      className: 'mb-2',
      onEvent: {
        click: {
          actions: [
            {
              actionType: 'setValue',
              componentId: 'form_data',
              args: {
                value: '${globalData}'
              }
            }
          ]
        }
      }
    },
    {
      type: 'form',
      id: 'form_data',
      title: '表单',
      debug: true,
      data: {
        myrole: '预言家',
        age: '18'
      },
      "initApi": "/api/mock2/form/initData",
      body: [
        {
          type: 'input-text',
          label: '角色',
          name: 'myrole',
          disabled: false,
          mode: 'horizontal'
        },
        {
          type: 'input-text',
          label: '年龄',
          name: 'age',
          disabled: false,
          mode: 'horizontal'
        }
      ]
    }
  ]
}
```

### 刷新组件请求

通过配置`actionType: 'reload'`刷新指定组件的数据请求，支持数据容器类组件（`form`、`wizard`、`service`、`page`、`app`、`chart`、`crud`）以及支持动态数据的`输入类`组件，详见组件的`动作表`。更多示例请查看[刷新示例](../../../examples/action/reload/form)。

#### 刷新输入类组件

针对支持远程数据的输入类组件，支持刷新目标组件的数据请求。

```schema
{
  type: 'page',
  body: [
    {
      type: 'button',
      label: '刷新下拉框',
      className: 'mb-2',
      level: 'primary',
      onEvent: {
        click: {
          actions: [
            {
              actionType: 'reload',
              componentId: 'select-reload'
            }
          ]
        }
      }
    },
    {
      type: 'form',
      title: '表单',
      body: [
        {
          type: 'select',
          id: 'select-reload',
          name: 'select',
          label: '选项',
          "source": "/api/mock2/form/getOptions?waitSeconds=1"
        }
      ]
    }
  ]
}
```

#### 刷新 CRUD

刷新 CRUD 时，如果配置了`data`，将发送`data`给目标 CRUD 组件，并将该数据合并到目标 CRUD 组件的数据域中，然后触发目标组件的刷新操作，即 CRUD 数据拉取接口将自动追加`data`参数到请求中，更多示例可以查看[CRUD reload](../../components/crud#reload)。

```
/* Detailed source-code truncated for AI context efficiency. */
```

#### 刷新其他数据容器类组件

刷新容器类组件（`form`、`wizard`、`service`、`page`、`app`、`chart`）时，如果配置了`data`，将发送`data`给目标组件，并将该数据合并到目标组件的数据域中。

```schema
{
  "type": "page",
  "body": [
    {
      "type": "button",
      "label": "刷新Service数据加载请求，同时把年龄更新为18",
      level: 'primary',
      "className": "mb-2",
      "onEvent": {
        "click": {
          "actions": [
            {
              "componentId": "service_reload",
              "actionType": "reload",
              data: {
                age: "18"
              }
            }
          ]
        }
      }
    },
    {
      "type": "service",
      "api": "/api/mock2/form/initData",
      "body": [
        {
          "type": "tpl",
          "tpl": "我的名字：${name}, 我的年龄：${age|default:'-'}",
          "wrapperComponent": "",
          "inline": false
        }
      ],
      "id": "service_reload"
    }
  ]
}
```

#### 获得刷新后的结果

> 6.9.0 及以上版本

通过配置 outputVar 可以拿到刷新后的结果，例如以下示例，点击按钮后，会串行按顺序刷新 service 1 和 service2， 同时 service2 可以拿到 service1 的返回值。

```schema
{
  "type": "page",
  "body": [
    {
      "type": "button",
      "label": "刷新Service数据",
      "level": "primary",
      "className": "mb-2",
      "onEvent": {
        "click": {
          "actions": [
            {
              "componentId": "service_reload",
              "actionType": "reload",
              "outputVar": "service1"
            },
            {
              "actionType": "toast",
              "args": {
                "msgType": "info",
                "msg": "service 的数据返回为： ${service1|json}"
              }
            },
            {
              "componentId": "service_reload2",
              "actionType": "reload",
              "data": {
                "date": "${service1.date}"
              }
            }
          ]
        }
      }
    },
    {
      "type": "service",
      "api": {
        "method": "get",
        "url": "/api/mock2/form/initData",
        "trackExpression": "none"
      },
      "body": [],
      "initFetch": false,
      "id": "service_reload"
    },
    {
      "type": "service",
      "api": {
        "method": "get",
        "url": "/api/mock2/form/initData?date=${date}",
        "trackExpression": "none"
      },
      "body": [],
      "initFetch": false,
      "id": "service_reload2"
    }
  ]
}
```

**动作属性**

| 属性名    | 类型      | 默认值 | 说明                                                               |
| --------- | --------- | ------ | ------------------------------------------------------------------ |
| resetPage | `boolean` | true   | 当目标组件为 `crud` 时，可以控制是否重置页码，`> 2.3.2 及以上版本` |

**其他属性**

| 属性名      | 类型     | 默认值 | 说明                  |
| ----------- | -------- | ------ | --------------------- |
| componentId | `string` | -      | 指定刷新的目标组件 id |

### 修改组件状态

> 1.8.0 及以上版本

通过配置`actionType: 'show'`或`'hidden'`或`'enabled'`或`'disabled'`或`'static'`或`'nonstatic'`实现对指定组件的显示、隐藏、启用、禁用，仅支持实现了对应状态控制功能的数据`输入类`组件。

#### 显示与隐藏

```schema
{
  type: 'page',
  body: [
    {
      type: 'button',
      label: '显示表单',
      level: 'primary',
      className: 'mr-2 mb-2',
      onEvent: {
        click: {
          actions: [
            {
              actionType: 'show',
              componentId: 'form_hidden'
            }
          ]
        }
      }
    },
    {
      type: 'button',
      label: '隐藏表单',
      level: 'primary',
      className: 'mr-2 mb-2',
      onEvent: {
        click: {
          actions: [
            {
              actionType: 'hidden',
              componentId: 'form_hidden'
            }
          ]
        }
      }
    },
    {
      type: 'form',
      id: 'form_hidden',
      title: '表单',
      body: [
        {
          "type": "input-text",
          "name": "text",
          "label": "输入框",
          "mode": "horizontal",
          "value": "text"
        }
      ]
    }
  ]
}
```

#### 启用与禁用

```
/* Detailed source-code truncated for AI context efficiency. */
```

#### 静态展示与编辑态

```schema
{
  type: 'page',
  body: [
    {
      type: 'button',
      label: '静态展示表单',
      level: 'primary',
      className: 'mr-2 mb-2',
      onEvent: {
        click: {
          actions: [
            {
              actionType: 'static',
              componentId: 'form_static'
            }
          ]
        }
      }
    },
    {
      type: 'button',
      label: '非静态展示表单',
      level: 'primary',
      className: 'mr-2 mb-2',
      onEvent: {
        click: {
          actions: [
            {
              actionType: 'nonstatic',
              componentId: 'form_static'
            }
          ]
        }
      }
    },
    {
      type: 'form',
      id: 'form_static',
      title: '表单',
      body: [
        {
          "type": "input-text",
          "name": "text",
          "label": "输入框",
          "mode": "horizontal",
          "value": "text"
        }
      ]
    }
  ]
}
```

**其他属性**

| 属性名      | 类型     | 默认值 | 说明                                 |
| ----------- | -------- | ------ | ------------------------------------ |
| componentId | `string` | -      | 指定启用/禁用/显示/隐藏的目标组件 id |

### 执行目标组件的动作

例如，点击按钮后，切换选项卡。

```schema
{
  type: 'page',
  body: [
    {
      type: 'button',
      label: '选中选项卡2',
      level: 'primary',
      className: 'mr-3 mb-3',
      onEvent: {
        click: {
          actions: [
            {
              actionType: 'changeActiveKey',
              componentId: 'tabs-change-receiver',
              args: {
                activeKey: 2
              }
            }
          ]
        }
      }
    },
    {
      id: 'tabs-change-receiver',
      type: 'tabs',
      mode: 'line',
      tabs: [
        {
          title: '选项卡1',
          body: '选项卡内容1'
        },
        {
          title: '选项卡2',
          body: '选项卡内容2'
        },
        {
          title: '选项卡3',
          body: '选项卡内容3'
        }
      ]
    }
  ]
}
```

## 触发广播

通过配置`actionType: 'broadcast'`实现触发一个广播。

```
/* Detailed source-code truncated for AI context efficiency. */
```

**动作属性（args）**

> `< 2.3.2 及以下版本`，以下属性与 args 同级。

| 属性名    | 类型     | 默认值 | 说明                                             |
| --------- | -------- | ------ | ------------------------------------------------ |
| eventName | `string` | -      | 广播动作对应的自定义事件名称，用于广播事件的监听 |

**其他属性**

| 属性名 | 类型     | 默认值 | 说明                                                     |
| ------ | -------- | ------ | -------------------------------------------------------- |
| weight | `number` | 0      | 可以通过配置动作执行优先级来控制所有监听者的动作执行顺序 |

## 注册自定义动作

除了以上内置动作，你还可以注册自己的动作。通过对`RendererAction`的`run`方法的实现可以定制自己的动作逻辑，最后通过`registerAction`注册到 amis 事件动作中。

```javascript
import {
  ListenerAction,
  ListenerContext,
  registerAction,
  RendererAction
} from 'amis-core';
import {RendererEvent} from 'amis-core';

// 动作定义
interface IMyAction extends ListenerAction {
  actionType: 'my-action';
  args: {
    param1: string, // 动作参数1
    param2: string // 动作参数2
  };
}

/**
 * 我的动作实现
 */
export class MyAction implements RendererAction {
  run(action: IMyAction, renderer: ListenerContext, event: RendererEvent<any>) {
    const props = renderer.props;
    const {param1, param2} = action.args;

    // 你的动作逻辑
    // ...
  }
}

// 注册自定义动作
registerAction('my-action', new MyAction());
```

# 编排动作

通过配置不同的逻辑动作实现动作编排，支持嵌套。

## 条件

通过配置`expression: 表达式或ConditionBuilder组合条件`来实现条件逻辑。

```
/* Detailed source-code truncated for AI context efficiency. */
```

**其他属性**

| 属性名     | 类型                                        | 默认值 | 说明                         |
| ---------- | ------------------------------------------- | ------ | ---------------------------- |
| expression | `boolean`\|[表达式](../concepts/expression) | -      | 执行条件，不设置表示默认执行 |

## 循环

通过配置`actionType: 'loop'`实现循环逻辑。

### 单层循环

```schema
{
  type: 'page',
  body: {
    type: 'form',
    wrapWithPanel: false,
    data: {
      loopName: 'loopData',
      loopData: [
        {
          name: 'lv',
          age: '19'
        },
        {
          name: 'xj',
          age: '21'
        }
      ]
    },
    body: [
      {
        type: 'button',
        label: '循环发送两次请求，且每次携带了循环的数据',
        level: 'primary',
        onEvent: {
          click: {
            actions: [
              {
                actionType: 'loop',
                args: {
                  loopName: '${loopName}'
                },
                children: [
                  {
                    actionType: 'ajax',
                    args: {
                      api: 'https://3xsw4ap8wah59.cfc-execute.bj.baidubce.com/api/amis-mock/mock2/form/saveForm?name=${name}&age=${age}'
                    }
                  }
                ]
              }
            ]
          }
        }
      }
    ]
  }
}
```

### 嵌套循环

```
/* Detailed source-code truncated for AI context efficiency. */
```

**动作属性（args）**

> `< 1.8.0 及以下版本`，以下属性与 args 同级。

| 属性名   | 类型     | 默认值 | 说明         |
| -------- | -------- | ------ | ------------ |
| loopName | `string` | -      | 循环变量名称 |

**其他属性**

> `< 2.3.2 及以下版本`，以下属性与 args 同级。

| 属性名   | 类型                                                 | 默认值 | 说明                                  |
| -------- | ---------------------------------------------------- | ------ | ------------------------------------- |
| children | Array<[动作](../../docs/concepts/event-action#动作)> | -      | 子动作，可以通过`break动作`来跳出循环 |

### Break 动作

通过配置`actionType: 'loop'`和`actionType: 'break'`实现循环跳出。

```schema
{
  type: 'page',
  body: {
    type: 'form',
    wrapWithPanel: false,
    data: {
      loopName: 'loopData',
      loopData: [
        {
          name: 'lv',
          age: '19'
        },
        {
          name: 'xj',
          age: '21'
        }
      ]
    },
    body: [
      {
        type: 'button',
        label: '只执行了第一个动作就跳出了循环',
        level: 'primary',
        onEvent: {
          click: {
            actions: [
              {
                actionType: 'loop',
                args: {
                  loopName: '${loopName}'
                },
                children: [
                  {
                    actionType: "toast",
                    args: {
                      msgType: 'success',
                      msg: '第 1 个动作',
                      position: 'top-right'
                    }
                  },
                  {
                    actionType: 'break'
                  },
                  {
                    actionType: "toast",
                    args: {
                      msgType: 'success',
                      msg: '第 2 个动作',
                      position: 'top-right'
                    }
                  }
                ]
              }
            ]
          }
        }
      }
    ]
  }
}
```

### Continue 动作

通过配置`actionType: 'loop'`和`actionType: 'continue'`实现循环跳过。

```schema
{
  type: 'page',
  body: {
    type: 'form',
    wrapWithPanel: false,
    data: {
      loopName: 'loopData',
      loopData: [
        {
          name: 'lv',
          age: '19'
        },
        {
          name: 'xj',
          age: '21'
        }
      ]
    },
    body: [
      {
        type: 'button',
        label: '只循环执行第一个动作',
        level: 'primary',
        onEvent: {
          click: {
            actions: [
              {
                actionType: 'loop',
                args: {
                  loopName: '${loopName}',
                  level: 3
                },
                children: [
                  {
                    actionType: "toast",
                    args: {
                      msgType: 'success',
                      msg: '第 1 个动作',
                      position: 'top-right'
                    }
                  },
                  {
                    actionType: 'continue'
                  },
                  {
                    actionType: "toast",
                    args: {
                      msgType: 'success',
                      msg: '最后的动作',
                      position: 'top-right'
                    }
                  }
                ]
              }
            ]
          }
        }
      }
    ]
  }
}
```

## 排他（switch）

通过配置`actionType: 'switch'`实现排他逻辑。

```schema
{
  type: 'page',
  body: {
    type: 'form',
    wrapWithPanel: false,
    data: {
      branchCont: 18
    },
    body: [
      {
        type: 'button',
        label: '只执行动作2',
        level: 'primary',
        onEvent: {
          click: {
            actions: [
              {
                actionType: 'switch',
                children: [
                  {
                    actionType: "toast",
                    args: {
                      msgType: 'info',
                      msg: '动作1',
                      position: 'top-right'
                    },
                    expression: 'this.branchCont > 19',
                    stopPropagation: true // 这里无效，因为条件不成立
                  },
                  {
                    actionType: "toast",
                    args: {
                      msgType: 'info',
                      msg: '动作2',
                      position: 'top-right'
                    },
                    expression: 'this.branchCont > 17'
                  },
                  {
                    actionType: "toast",
                    args: {
                      msgType: 'info',
                      msg: '动作3',
                      position: 'top-right'
                    },
                    expression: 'this.branchCont > 16'
                  }
                ]
              }
            ]
          }
        }
      }
    ]
  }
}
```

**其他属性**

| 属性名   | 类型                                                 | 默认值 | 说明                                                   |
| -------- | ---------------------------------------------------- | ------ | ------------------------------------------------------ |
| children | Array<[动作](../../docs/concepts/event-action#动作)> | -      | 子动作，每个子动作可以通过配置`expression`来匹配的条件 |

## 并行

通过配置`actionType: 'parallel'`实现并行执逻辑。

```
/* Detailed source-code truncated for AI context efficiency. */
```

**其他属性**

| 属性名   | 类型                                                 | 默认值 | 说明   |
| -------- | ---------------------------------------------------- | ------ | ------ |
| children | Array<[动作](../../docs/concepts/event-action#动作)> | -      | 子动作 |

# 动作间数据传递

从事件触发开始，整个数据流包含事件本身产生的事件数据和动作产生的动作数据，事件源头产生的数据在 AMIS 事件动作机制底层已经自动加入渲染器数据域，可以通过`xxx`直接获取（`< 2.3.2 及以下版本 为 event.data.xxx`），而部分动作产生的数据如何流动需要交互设计者进行介入，对于数据流动可以通过数据映射，将上一个动作产生的数据作为动作参数写入下一个动作。

#### 传递数据

通过 `data` 指定输入的参数数据（`< 2.3.2 及以下版本`通过`args`传递数据），它是一个键值对。

```schema
{
  type: 'page',
  body: [
    {
      type: 'button',
      id: 'b_001',
      label: '发一个广播，携带动作参数',
      className: 'mb-2',
      level: 'primary',
      onEvent: {
        click: {
          actions: [
            {
              actionType: 'broadcast',
              args: {
                eventName: 'broadcast_1',
              },
              data: {
                name: 'lvxj',
                age: 18
              },
              description: '一个按钮的点击事件'
            }
          ]
        }
      }
    },
    {
      type: 'form',
      name: 'form1',
      id: 'form_001',
      title: '接收广播事件的参数',
      debug: true,
      body: [
        {
          type: 'input-text',
          id: 'form_001_text_01',
          label: '年龄',
          name: 'age',
          disabled: false,
          mode: 'horizontal'
        }
      ],
      data: {
        name: 'amis'
      },
      onEvent: {
        broadcast_1: {
          actions: [
            {
              actionType: 'reload',
              data: {
                age: '${age}',
                name: '${name}'
              }
            }
          ]
        }
      }
    }
  ]
}
```

#### 引用 http 请求返回的数据

http 请求动作执行结束后，后面的动作可以通过 `${responseResult}`或`${{outputVar}}`来获取请求响应结果，响应结果的结构定义参考[发送 http 请求](../../docs/concepts/event-action#发送-http-请求)。

> `< 2.3.2 及以下版本 需要通过 ${event.data.{xxx}}`来获取以上信息，例如：${event.data.responseResult}

```schema
{
  type: 'page',
  body: [
    {
      type: 'button',
      label: '发送Ajax请求，并把返回数据传给弹窗',
      level: 'primary',
      onEvent: {
        click: {
          actions: [
            {
              actionType: 'ajax',
              args: {
                api: 'https://3xsw4ap8wah59.cfc-execute.bj.baidubce.com/api/amis-mock/mock2/form/saveForm'
              }
            },
            {
              actionType: 'dialog',
              data: {
                id: '${event.data.responseResult.responseData.id}'
              },
              dialog: {
                type: 'dialog',
                id: 'dialog_005',
                title: '弹框标题1',
                data: {
                  id: '${id}'
                },
                body: [
                  {
                    type: 'form',
                    body: [
                      {
                        type: 'tpl',
                        tpl: '<p>请求返回的数据：id=${id}</p>',
                        inline: false
                      }
                    ]
                  }
                ]
              }
            }
          ]
        }
      }
    }
  ]
}
```

#### 获取组件相关数据

可以通过表达式函数`GETRENDERERDATA(id, path)`和`GETRENDERERPROP(id, path)`分别获取指定组件的数据和属性。

```schema
{
  type: 'page',
  body: [
    {
      type: 'form',
      id: 'form_get_render',
      wrapWithPanel: false,
      data: {
        name: 'amis',
        age: '18'
      },
      body: [
        {
          type: 'input-text',
          name: 'name',
          label: 'name'
        },
        {
          type: 'input-text',
          name: 'age',
          label: 'age'
        }
      ],
      className: 'mb-2',
    },
    {
      type: 'button',
      className: 'mt-2',
      label: '获取表单相关数据',
      level: 'primary',
      onEvent: {
        click: {
          actions: [
            {
              actionType: 'toast',
              args: {
                msg: 'name:${GETRENDERERDATA("form_get_render", "name")},type:${GETRENDERERPROP("form_get_render", "type")}'
              }
            }
          ]
        }
      }
    }
  ]
}
```

该函数参数说明如下：

| 参数名 | 说明                          |
| ------ | ----------------------------- |
| id     | 组件 ID，即组件的 id 属性的值 |
| path   | 数据路径，即数据变量的路径    |

# 干预动作执行

事件动作干预是指执行完当前动作后，干预所监听事件默认处理逻辑和后续其他动作的执行。通过`preventDefault`、`stopPropagation`分别阻止监听事件默认行为和停止下一个动作执行。

## 阻止事件默认行为

有些组件内置了一些逻辑来帮助用户降低配置成本，但可能这些逻辑并不符合设计者的业务需求，这时可以通过`onEvent`来监听对应的事件，并通过`preventDefault`来阻止那些默认处理逻辑来达到想要的最终效果。更多示例请查看[阻止组件默认行为示例](../../../examples/action/prevent/form)。

```schema
{
  type: 'page',
  title: '弹窗确认后执行其他动作并阻止默认关闭',
  body: [
    {
      type: 'button',
      className: 'ml-2',
      label: '打开弹窗',
      level: 'primary',
      onEvent: {
        click: {
          actions: [
            {
              actionType: 'dialog',
              dialog: {
                type: 'dialog',
                title: '提示',
                id: 'dialog_001',
                data: {
                   myage: '22'
                },
                body: [
                  {
                    type: 'alert',
                    body: '输入Do not close，确认后将不关闭弹窗',
                    level: 'warning'
                  },
                  {
                    type: 'input-text',
                    name: 'command'
                  }
                ],
                onEvent: {
                  confirm: {
                    actions: [
                      {
                        actionType: 'toast',
                        args: {
                          msg: '不关闭'
                        },
                        preventDefault: 'command === "Do not close"'
                      }
                    ]
                  }
                }
              }
            }
          ]
        }
      }
    }
  ]
}
```

> 6.3.0 版本开始支持

或者直接通过动作来阻止

```json
{
  "actionType": "preventDefault",
  "expression": "${command === 'Do not close'}"
}
```

```schema
{
  type: 'page',
  title: '弹窗确认后执行其他动作并阻止默认关闭',
  body: [
    {
      type: 'button',
      className: 'ml-2',
      label: '打开弹窗',
      level: 'primary',
      onEvent: {
        click: {
          actions: [
            {
              actionType: 'dialog',
              dialog: {
                type: 'dialog',
                title: '提示',
                id: 'dialog_001',
                data: {
                   myage: '22'
                },
                body: [
                  {
                    type: 'alert',
                    body: '输入Do not close，确认后将不关闭弹窗',
                    level: 'warning'
                  },
                  {
                    type: 'input-text',
                    name: 'command'
                  }
                ],
                onEvent: {
                  confirm: {
                    actions: [
                      {
                        "actionType": "preventDefault",
                        "expression" : "${command === 'Do not close'}"
                      }
                    ]
                  }
                }
              }
            }
          ]
        }
      }
    }
  ]
}
```

## 停止后续动作执行

通过`onEvent`可以对监听的事件配置一组动作，这些动作是顺序执行的，有时间设计者希望执行某个/些动作后就停止继续执行后面的动作，这时候可以通过`stopPropagation`来停止执行后面配置的所有动作。

```schema
{
  "type": "page",
  "title": "只执行3个动作中的前两个动作",
  "body": [
    {
      "type": "button",
      "label": "弹出2个提示",
      level: 'primary',
      "onEvent": {
        "click": {
          "actions": [
            {
              "actionType": "toast",
              args: {
                "msgType": 'info',
                "msg": '动作1'
              }
            },
            {
              "actionType": "toast",
              args: {
                "msgType": 'info',
                "msg": '动作2'
              },
              "stopPropagation": true
            },
            {
              "actionType": "toast",
              args: {
                "msgType": 'info',
                "msg": '动作3',
                "position": 'top-right'
              }
            }
          ]
        }
      }
    }
  ]
}
```

> 6.3.0 版本开始支持

或者直接通过动作来跳过后续逻辑

```json
{
  "actionType": "stopPropagation",
  "expression": "${command === 'Do not close'}"
}
```

```schema
{
  "type": "page",
  "title": "只执行第一个动作",
  "body": [
    {
      "type": "button",
      "label": "弹出一个提示",
      level: 'primary',
      "onEvent": {
        "click": {
          "actions": [
            {
              "actionType": "toast",
              args: {
                "msgType": 'info',
                "msg": '后续的动作将不会执行'
              }
            },
            {
              "actionType": "stopPropagation",
              "expression": "${true}"
            },
            {
              "actionType": "toast",
              args: {
                "msgType": 'info',
                "msg": '动作2'
              },
            },
            {
              "actionType": "toast",
              args: {
                "msgType": 'info',
                "msg": '动作3'
              }
            }
          ]
        }
      }
    }
  ]
}
```

## 忽略动作报错继续执行

> `3.3.1` 及以上版本

默认情况下，尝试执行一个不存在的目标组件动作、JS 脚本执行错误等程序错误都会导致动作执行终止，可以通过`ignoreError: true`来忽略动作报错继续执行后面的动作。

```schema
{
  "type": "page",
  "title": "第一个按钮发生错误直接阻塞执行，第二个按钮发生错误后仍然执行",
  "body": [
    {
      type: 'button',
      label: '无法弹出提示',
      level: 'primary',
      className: 'mr-2',
      onEvent: {
        click: {
          actions: [
            {
              actionType: 'reload',
              componentId: 'notfound'
            },
            {
              actionType: 'toast',
              args: {
                msg: 'okk'
              }
            }
          ]
        }
      }
    },
    {
      type: 'button',
      label: '可以弹出提示',
      level: 'primary',
      onEvent: {
        click: {
          actions: [
            {
              actionType: 'reload',
              componentId: 'notfound',
              ignoreError: true
            },
            {
              actionType: 'toast',
              args: {
                msg: 'okk'
              }
            }
          ]
        }
      }
    }
  ]
}
```

# 自定义组件接入事件动作

需求场景主要是想要自定义组件的内部事件暴露出去，能够通过对事件的监听来执行所需动作，并希望自定义组件自身的动作能够被其他组件调用。接入方法是通过`props.dispatchEvent`派发自身的各种事件，使其具备更灵活的交互设计能力；通过实现`doAction`方法实现其他组件对其专属动作的调用，需要注意的是，此处依赖内部的 `Scoped Context`来实现自身的注册，可以参考 [组件间通信](../../docs/extend/custom-react#组件间通信)。

# 属性表

| 属性名          | 类型                                                                                                     | 默认值  | 说明                                                                                                          |
| --------------- | -------------------------------------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------- |
| actionType      | `string`                                                                                                 | -       | 动作名称                                                                                                      |
| args            | `object`                                                                                                 | -       | 动作属性`{key:value}`，支持数据映射                                                                           |
| data            | `object`                                                                                                 | -       | 追加数据`{key:value}`，支持数据映射，如果是触发其他组件的动作，则该数据会传递给目标组件，`> 2.3.2 及以上版本` |
| dataMergeMode   | `string`                                                                                                 | 'merge' | 当配置了 data 的时候，可以控制数据追加方式，支持合并(`merge`)和覆盖(`override`)两种模式，`> 2.3.2 及以上版本` |
| preventDefault  | `boolean`\|[表达式](../concepts/expression)\|[ConditionBuilder](../../components/form/condition-builder) | false   | 阻止事件默认行为，`> 1.10.0 及以上版本支持表达式，> 2.9.0 及以上版本支持ConditionBuilder`                     |
| stopPropagation | `boolean`\|[表达式](../concepts/expression)\|[ConditionBuilder](../../components/form/condition-builder) | false   | 停止后续动作执行，`> 1.10.0 及以上版本支持表达式，> 2.9.0 及以上版本支持ConditionBuilder`                     |
| expression      | `boolean`\|[表达式](../concepts/expression)\|[ConditionBuilder](../../components/form/condition-builder) | -       | 执行条件，不设置表示默认执行，`> 1.10.0 及以上版本支持表达式，> 2.9.0 及以上版本支持ConditionBuilder`         |
| outputVar       | `string`                                                                                                 | -       | 输出数据变量名                                                                                                |
| ignoreError     | `boolean`                                                                                                | false   | 当动作执行出错后，是否忽略错误继续执行。`3.3.1 及以上版本支持`                                                |

---

### Zh CN Concepts Expression (`docs/zh-CN/concepts/expression.md`)

---
title: 表达式
description:
type: 0
group: 💡 概念
menuName: 表达式
icon:
order: 13
---

## 使用场景

amis 中有很多场景会用到表达式。

- 模板中变量取值。 如：`my name is ${xxx}`
- api 地址参数取值 如 `http://mydomain.com/api/xxx?id=${id}`
- api 发送&接收数据映射

  ```
  {
    "type": "crud",
    "api": {
      method: "post"
      url: "http://mydomain.com/api/xxx",
      data: {
        skip: "${(page - 1) * perPage}",
        take: "${perPage}"
      }
    },
    ...
  }
  ```

- 组件显示与隐藏条件

  ```
  {
    "name": "xxxText",
    "type": "input-text",
    "visibleOn": "${ xxxFeature.on }"
  }
  ```

- 表单默认值

  ```
  {
    "name": "xxxText",
    "type": "input-text",
    "value": "${ TODAY() }"
  }
  ```

- 等等

amis 中表达式有两种语法：

- 一种是纯 js 表达式，如 `data.xxx === 1`。
- 另一种是用 `${` 和 `}` 包裹的表达式。如：`${ xxx === 1}`。

```json
{
  "type": "tpl",
  "tpl": "当前作用域中变量 show 是 1 的时候才可以看得到我哦~",
  "visibleOn": "${show === 1}"
}
```

第一种是早期的版本，偷懒直接用的 [Javascript](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript)，灵活性虽高，但是安全性欠佳。建议使用新版本规则，新规则跟 tpl 模板取值规则完全一样，不用来回切换语法。

## 表达式语法

表达式主要由三部分组成：开始字符、表达式内容和结束字符。其中开始字符固定是 `${` 结束字符固定是 `}`，中间内容才是表达式正文。这里说的语法主要还是表达式正文的语法。

规则主要包含：

- 变量名： `xxx变量`、`xxx变量.xxx属性`、`xxx变量[xxx属性]`
- 布尔值： `true` 或者 `false`
- null：`null`
- undefined: `undefined`
- 数字： `123` 或者 `123.23`
- 字符串： `"string"` 或者 `'string'`
- 字符模板

  ```
  `my name is ${name}`
  ```

- 数组： `[1, 2, 3]`
- 对象： `{a: 1, b: 2}`
- 组合使用如： `{a: 1: b: [1, 2, 3], [key]: yyy变量}`
- 三元表达式： `xx变量 == 1 ? 2 : 3`
- 二元表达式： `xx变量 && yy 变量` 、 `xx变量 || yy 变量`、 `xx变量 == 123`

  - `+` 相加
  - `-` 相减
  - `*` 乘
  - `/` 除
  - `**` pow 运算
  - `||` 或者
  - `&&` 并且
  - `|` 或运算
  - `^` 异或运算
  - `&` 与运算
  - `==` 等于比较
  - `!=` 不等于
  - `===` 恒等于
  - `!==` 不恒等于
  - `<` 小于
  - `<=` 小于或等于
  - `>` 大于
  - `>=` 大于或等于
  - `<<` 左移
  - `>>` 右移
  - `>>>` 带符号位的右移运算符

- 一元表达式： `!xx变量`、`~xx变量`

* `+` 一元加法
* `-` 一元减法
* `~` 否运算符，加 1 取反
* `!` 取反

- 函数调用：`SUM(1, 2, 3)`
- 箭头函数：`() => abc` 注意这个箭头函数只支持单表达式，不支持多条语句。主要配置其他函数使用如：`ARRAY_MAP(arr, item => item.abc)`
- 括号包裹，修改运算优先级：`(10 - 2) * 3`

示例：

```schema
{
  "type": "page",
  "data": {
    "a": 1,
    "key": "y",
    "obj": {
      "x": 2,
      "y": 3
    },
    "arr": [1, 2, 3]
  },
  "body": [
    "a is ${a} <br />",
    "a + 1 is ${a + 1} <br />",
    "obj.x is ${obj.x} <br />",
    "obj['x'] is ${obj['x']} <br />",
    "obj[key] is ${obj[key]} <br />",
    "arr[0] is ${arr[0]} <br />",
    "arr[a] is ${arr[a]} <br />",
    "arr[a + 1] is ${arr[a + 1]} <br />"
  ]
}
```

_特殊字符变量名_

> 1.6.1 及以上版本

默认变量名不支持特殊字符比如 `${ xxx.yyy }` 意思取 xxx 变量的 yyy 属性，如果变量名就是 `xxx.yyy` 怎么获取？这个时候需要用到转义语法，如：`${ xxx\.yyy }`

### 公式

除了支持简单表达式外，还集成了很多公式(函数)如 `${ AVG(1, 2, 3, 4)}`：

```schema
{
  "type": "page",
  "data": {
    "a": "",
    "语文成绩": 81
  },
  "body": [
    "1, 2, 3, 4 的平均数位 ${ AVG(1, 2, 3, 4)}",

    "当前成绩：${IF(语文成绩 > 80, '优秀', '继续努力')}"
  ]
}
```

## 函数调用示例

函数支持嵌套，参数支持常量及变量

```schema
{
  "type": "page",
  "body": [
    {
      "type": "form",
      "wrapWithPanel": false,
      "data": {
        "val": 3.5
      },
      "body": [
        {
          "type": "static",
          "label": "IF(true, 2, 3)",
          "tpl": "${IF(true, 2, 3)}"
        },
        {
          "type": "static",
          "label": "MAX(1, -1, 2, 3, 5, -9)",
          "tpl": "${MAX(1, -1, 2, 3, 5, -9)}"
        },
        {
          "type": "static",
          "label": "ROUND(3.5)",
          "tpl": "${ROUND(3.5)}"
        },
        {
          "type": "static",
          "label": "ROUND(val)",
          "tpl": "${ROUND(val)}"
        },
        {
          "type": "static",
          "label": "AVG(4, 6, 10, 10, 10)",
          "tpl": "${AVG(4, 6, 10, 10, 10)}"
        },
        {
          "type": "static",
          "label": "UPPERMONEY(7682.01)",
          "tpl": "${UPPERMONEY(7682.01)}"
        },
        {
          "type": "static",
          "label": "TIMESTAMP(DATE(2021, 11, 21, 0, 0, 0), 'x')",
          "tpl": "${TIMESTAMP(DATE(2021, 11, 21, 0, 0, 0), 'x')}"
        },
        {
          "type": "static",
          "label": "DATETOSTR(NOW(), 'YYYY-MM-DD')",
          "tpl": "${DATETOSTR(NOW(), 'YYYY-MM-DD')}"
        }
      ]
    }
  ]
}
```

下面是目前所支持函数的使用手册

!!!include(amis-formula/lib/doc.md)!!!

---

### Zh CN Concepts Linkage (`docs/zh-CN/concepts/linkage.md`)

---
title: 联动
description:
type: 0
group: 💡 概念
menuName: 联动
icon:
order: 14
---

上一节我们介绍了表达式的概念，而表达式应用最多的场景，是实现页面的联动效果。

## 基本联动

元素的联动是页面开发中很常见的功能之一，类似于：

- 某个条件下显示或隐藏某个组件
- 某个条件下请求接口
- 某个条件下轮询接口停止轮询
- 等等...

> 联动配置项一般都是 [表达式](./expression)

### 组件配置联动

控制组件的显隐，表单项的禁用状态等，看下面这个例子：

```schema: scope="body"
{
    "type": "form",
    "body": [
        {
            "type": "radios",
            "name": "foo",
            "label": false,
            "options": [
                {
                    "label": "类型1",
                    "value": 1
                },
                {
                    "label": "类型2",
                    "value": 2
                }
            ]
        },
        {
            "type": "input-text",
            "name": "text1",
            "label": false,
            "placeholder": "选中 类型1 时可见",
            "visibleOn": "${foo == 1}"
        },
        {
            "type": "input-text",
            "name": "text2",
            "label": false,
            "placeholder": "选中 类型2 时不可点",
            "disabledOn": "${foo == 2}"
        }
    ]
}
```

上面实例主要为一个表单，表单内有三个组件：一个`radio`, 两个`text`，通过配置联动配置项，实现下面联动效果：

1. 只要当`radio`选中`类型1`时，才会显示`text1`；
2. 当`radio`选中`类型2`时，`text2`将会变为`禁用状态`

> **注意：**
>
> 在表单项联动中，为了方便数据的读取，赋值后或者修改过的表单项，通过隐藏后，并不会在当前数据域中删除掉该字段值，因此默认提交的时候可能仍然会带上已隐藏表单项的值。
>
> 如果想要在提交时去掉某个隐藏的字段，可以通过添加 [clearValueOnHidden](../../components/form/formitem#隐藏时删除表单项值) 属性实现。

### 接口联动

#### 基本使用

接口联动是另外一种很常见的场景，查看下面这个例子：

```schema: scope="body"
{
    "title": "",
    "type": "form",
    "mode": "horizontal",
    "body": [
      {
        "label": "选项1",
        "type": "radios",
        "name": "a",
        "inline": true,
        "options": [
          {
            "label": "选项A",
            "value": 1
          },
          {
            "label": "选项B",
            "value": 2
          },
          {
            "label": "选项C",
            "value": 3
          }
        ]
      },
      {
        "label": "选项2",
        "type": "select",
        "size": "sm",
        "name": "b",
        "source": "/api/mock2/options/level2?a=${a}",
        "description": "切换<code>选项1</code>的值，会触发<code>选项2</code>的<code>source</code> 接口重新拉取"
      }
    ],
    "actions": []
}
```

上面例子我们实现了这个逻辑：每次选择`选项1`的时候，会触发`选项2`的`source`配置的接口重新请求，并返回不同的下拉选项。

是如何做到的？

实际上，所有**初始化接口链接上使用数据映射获取参数的形式**时，例如下面的`query=${query}`，在当前数据域中，**所引用的变量值（即 query）发生变化时**，自动重新请求该接口。

```json
{
  "initApi": "/api/initData?query=${query}"
}
```

> **tip:**
>
> 触发所引用变量值发生变化的方式有以下几种：
>
> 1. 通过对表单项的修改，可以更改表单项`name`属性值所配置变量的值；
> 2. 通过[组件间联动](./linkage#%E7%BB%84%E4%BB%B6%E9%97%B4%E8%81%94%E5%8A%A8)，将其他组件的值发送到目标组件，进行数据域的更新，从而触发联动效果
>
> 接口联动一般只适用于初始化接口，例如：
>
> - `form`组件中的`initApi`；
> - `select`组件中的`source`选项源接口`url`, `data`只能用于主动联动；
> - `service`组件中的`api`和`schemaApi`；
> - `crud`组件中的`api`；（crud 默认是跟地址栏联动，如果要做请关闭同步地址栏 syncLocation: false）
> - 等等...

> 如果 api 地址中有变量，比如 `/api/mock2/sample/${id}`，amis 就不会自动加上分页参数，需要自己加上，改成 `/api/mock2/sample/${id}?page=${page}&perPage=${perPage}`

#### 配置请求条件

默认在变量变化时，总是会去请求联动的接口，你也可以配置请求条件，当只有当前数据域中某个值符合特定条件才去请求该接口。

```schema: scope="body"
{
    "title": "",
    "type": "form",
    "mode": "horizontal",
    "body": [
      {
        "label": "选项1",
        "type": "radios",
        "name": "a",
        "inline": true,
        "options": [
          {
            "label": "选项A",
            "value": 1
          },
          {
            "label": "选项B",
            "value": 2
          },
          {
            "label": "选项C",
            "value": 3
          }
        ]
      },
      {
        "label": "选项2",
        "type": "select",
        "size": "sm",
        "name": "b",
        "source": {
            "method": "get",
            "url": "/api/mock2/options/level2?a=${a}",
            "sendOn": "this.a === 2"
        },
        "description": "只有<code>选项1</code>选择<code>B</code>的时候，才触发<code>选项2</code>的<code>source</code>接口重新拉取"
      }
    ],
    "actions": []
}
```

更多用法，见：[Api-配置请求条件](../types/api#%E9%85%8D%E7%BD%AE%E8%AF%B7%E6%B1%82%E6%9D%A1%E4%BB%B6)

#### 主动触发

上面示例有个问题，就是数据一旦变化就会出发重新拉取，而输入框的频繁变化值会导致频繁的拉取？没关系，也可以配置主动拉取如：

```schema: scope="body"
{
    "type": "form",
    "name": "my_form",
    "body": [
      {
        "type": "input-text",
        "name": "keyword",
        "addOn": {
          "label": "搜索",
          "type": "button",
          "actionType": "reload",
          "target": "my_form.select"
        }
      },
      {
        "type": "select",
        "name": "select",
        "label": "Select",
        "source": {
          "method": "get",
          "url": "/api/mock2/form/getOptions?waitSeconds=1",
          "data": {
            "a": "${keyword}"
          }
        }
      }
    ]
}
```

1. 通过`api`对象形式，将获取变量值配置到`data`请求体中。
2. 配置搜索按钮，并配置该行为是刷新目标组件，并配置目标组件`target`
3. 这样我们只有在点击搜索按钮的时候，才会将`keyword`值发送给`select`组件，重新拉取选项

### 表单提交返回数据

表单提交后会将返回结果合并到当前表单数据域，因此可以基于它实现提交按钮后显示结果，比如

```schema: scope="body"
{
    "type": "form",
    "api": "/api/mock2/form/saveForm",
    "title": "查询用户 ID",
    "body": [
      {
        "type": "input-group",
        "name": "input-group",
        "body": [
           {
            "type": "input-text",
            "name": "name",
            "label": "姓名"
          },
          {
            "type": "submit",
            "label": "查询",
            "level": "primary"
          }
        ]
      },
      {
        "type": "static",
        "name": "id",
        "visibleOn": "typeof data.id !== 'undefined'",
        "label": "返回 ID"
      }
    ],
    "actions": []
}
```

上面的例子首先用 `"actions": []` 将表单默认的提交按钮去掉，然后在 `input-group` 里放一个 `submit` 类型的按钮来替代表单查询。

这个查询结果返回类似如下的数据

```json
{
  "status": 0,
  "msg": "保存成功",
  "data": {
    "id": 1
  }
}
```

amis 会将返回的 `data` 写入表单数据域，因此下面的 `static` 组件就能显示了。

### 其他联动

还有一些组件特有的联动效果，例如 form 的 disabledOn，crud 中的 itemDraggableOn 等等，可以参考相应的组件文档。

## 组件间联动

联动很可能会出现跨组件的形式，思考下面这种场景：

有一个表单`form`组件，还有一个列表组件`crud`，我们想要把`form`提交的数据，可以用作`crud`的查询条件，并请求`crud`的接口，由于`form`和`crud`位于同一层级，因此没法使用数据链的方式进行取值。

```schema: scope="body"
[
    {
      "title": "查询条件",
      "type": "form",
      "body": [
        {
          "type": "input-text",
          "name": "keywords",
          "label": "关键字："
        }
      ],
      "submitText": "搜索"
    },
    {
      "type": "crud",
      "api": "/api/mock2/sample",
      "columns": [
            {
                "name": "id",
                "label": "ID"
            },
            {
                "name": "engine",
                "label": "Rendering engine"
            },
            {
                "name": "browser",
                "label": "Browser"
            },
            {
                "name": "platform",
                "label": "Platform(s)"
            },
            {
                "name": "version",
                "label": "Engine version"
            }
        ]
    }
]
```

现在更改配置如下：

```schema: scope="body"
[
    {
      "title": "查询条件",
      "type": "form",
      "target": "my_crud",
      "body": [
        {
          "type": "input-text",
          "name": "keywords",
          "label": "关键字："
        }
      ],
      "submitText": "搜索"
    },
    {
      "type": "crud",
      "name": "my_crud",
      "api": "/api/mock2/sample",
      "columns": [
            {
                "name": "id",
                "label": "ID"
            },
            {
                "name": "engine",
                "label": "Rendering engine"
            },
            {
                "name": "browser",
                "label": "Browser"
            },
            {
                "name": "platform",
                "label": "Platform(s)"
            },
            {
                "name": "version",
                "label": "Engine version"
            }
        ]
    }
]
```

我们进行两个调整：

1. 为`crud`组件设置了`name`属性为`my_crud`
2. 为`form`组件配置了`target`属性为`crud`的`name`：`my_crud`

更改配置后，提交表单时，amis 会寻找`target`所配置的目标组件，把`form`中所提交的数据，发送给该目标组件中，并将该数据**合并**到目标组件的数据域中，并触发目标组件的刷新操作，对于 CRUD 组件来说，刷新即重新拉取数据接口。

> 当然，`crud`组件内置已经支持此功能，你只需要配置`crud`中的`filter`属性，就可以实现上面的效果，更多内容查看 [crud -> filter](../../components/crud) 文档。

我们再来一个例子，这次我们实现 [两个 form 之间的联动](../../components/form/index#%E5%B0%86%E6%95%B0%E6%8D%AE%E5%9F%9F%E5%8F%91%E9%80%81%E7%BB%99%E7%9B%AE%E6%A0%87%E7%BB%84%E4%BB%B6)

### 发送指定数据

`target`属性支持通过配置参数来发送指定数据，例如：`"target" :"xxx?a=${a}&b=${b}"`，这样就会把当前数据域中的`a`变量和`b`变量发送给目标组件

```schema: scope="body"
[
  {
    "type": "form",
    "title": "form1",
    "mode": "horizontal",
    "api": "/api/mock2/form/saveForm",
    "body": [
      {
        "label": "Name",
        "type": "input-text",
        "name": "name"
      },

      {
        "label": "Email",
        "type": "input-text",
        "name": "email"
      },

      {
        "label": "Company",
        "type": "input-text",
        "name": "company"
      }
    ],
    "actions": [
      {
        "type": "action",
        "actionType": "reload",
        "label": "发送到 form2",
        "target": "form2?name=${name}&email=${email}"
      }
    ]
  },
  {
    "type": "form",
    "title": "form2",
    "name": "form2",
    "mode": "horizontal",
    "api": "/api/mock2/form/saveForm",
    "body": [
      {
        "label": "MyName",
        "type": "input-text",
        "name": "name"
      },

      {
        "label": "MyEmail",
        "type": "input-text",
        "name": "email"
      },

      {
        "label": "Company",
        "type": "input-text",
        "name": "company"
      }
    ]
  }
]
```

上例中我们给按钮上配置了`"target": "form2?name=${name}&email=${email}"`,可以把当前数据链中的`name`变量和`email`变量发送给`form2`

### 配置多个目标

`target`支持配置多个目标组件 name，用逗号隔开，例如：

```json
{
  "type": "action",
  "actionType": "reload",
  "label": "刷新目标组件",
  "target": "target1,target2"
}
```

上例中点击按钮会刷新`target1`和`target2`组件。

事实上，**组件间联动也可以实现上述任意的 [基本联动效果](./linkage#%E5%9F%BA%E6%9C%AC%E8%81%94%E5%8A%A8)（显隐联动、接口联动等其他联动）。**

### 动态目标

> 2.9.0 及以上版本

刷新目标支持表达式，比如目标可以配置成 `form-${ xxx ? '1' : '2'}`。

```
/* Detailed source-code truncated for AI context efficiency. */
```

如果目标组件在列表中，则实际渲染的时候会存在多份，通过某个固定名字没办法找到对应的组件。比如某个 crud 里面，某列设置的是一个 service，通过 service 拉取数据。如果想在操作栏里面某个操作完后刷新对应的 service，通过固定的名字是没办法找到对应的 service 的。所以名字 `name` 也支持动态名字。如: `my-service-${id}` 把行数据中动态的 id 设置进去。

```schema: scope="body"
{
  type: 'crud',
  api: "/api/mock2/sample",
  columns: [
    {
      name: 'id',
      label: 'ID'
    },

    {
      type: 'service',
      api: "/api/mock2/sample/${id}",
      label: 'Service',
      name: "my-servce-${id}",
      body: [
        {
          type: "tpl",
          tpl: "${browser}"
        }
      ]
    },

    {
      type: 'operation',
      label: '操作',
      buttons: [
        {
          type: "button",
          label: "编辑",
          actionType: "dialog",
          dialog: {
            "title": "编辑",

            body: [
              {
                type: 'form',
                api: "/api/mock2/sample/${id}",
                body: [
                  {
                    type: 'input-text',
                    name: 'browser',
                    label: 'Browser'
                  }
                ]
              }
            ]
          },
          reload: "my-servce-${id}"
        }
      ]
    }
  ]
}
```

> 这个例子 api 是 mock 的，所以修改后刷新没效果。

---

### Zh CN Concepts Schema (`docs/zh-CN/concepts/schema.md`)

---
title: 配置与组件
description: 配置与组件
type: 0
group: 💡 概念
menuName: 配置与组件
icon:
order: 9
---

## 最简单的 amis 配置

一个最简单的 amis 配置看起来是这样的：

```json
{
  "type": "page",
  "body": "Hello World!"
}
```

请观察上面的代码，这是一段 JSON，它的含义是：

1. `type` 是 amis 节点中最重要的字段，它告诉 amis 当前节点需要渲染的是`Page`组件。
2. 而 `body` 字段会作为 `Page` 组件的属性，`Page` 组件根据这个值来渲染页面内容。

这段配置的效果如下所示：

```schema
{
  "type": "page",
  "body": "Hello World!"
}
```

上面这个配置是可以**实时修改预览**的，尝试改一下 `Hello World!` 的值。

> 不过这个实时预览功能对于某些属性不生效，如果发现不符合预期，需要复制 JSON，打开另一个页面后粘贴。

## 组件

上面提到，`type`字段会告诉 amis 当前节点渲染的组件为`Page`，组件节点的配置永远都是由 **`type`字段** （用于标识当前是哪个组件）和 **属性** 构成的。

```
{
  "type": "xxx",
  ...其它属性
}
```

## 组件树

这次我们看一个稍微复杂一点的配置：

```json
{
  "type": "page",
  "body": {
    "type": "tpl",
    "tpl": "Hello World!"
  }
}
```

该配置渲染页面如下：

```schema
{
  "type": "page",
  "body": {
    "type": "tpl",
    "tpl": "Hello World!"
  }
}
```

最终效果和前面的示例一样，但这次 `Page` 组件的 `body` 属性值配置了一个对象，**通过`type`指明`body`内容区内会渲染一个叫`Tpl`的组件**，它是一个模板渲染组件。

在 `body` 中除了配置对象，还可以是数组，比如下面的例子:

```schema: scope="body"
[
    {
      "type": "tpl",
      "tpl": "Hello World!"
    },
    {
        "type": "divider"
    },
    {
      "type": "form",
      "body": [
        {
          "type": "input-text",
          "name": "name",
          "label": "姓名"
        }
      ]
    }
]
```

可以看到通过数组的形式，增加了 `divider` 和 `form` 组件。

除了 `Page` 之外，还有很多**容器型**的组件都有 `body` 属性，通过这种树形结构，amis 就能实现复杂页面制作。

> **注意：**
>
> `Page`是 amis 页面配置中 **必须也是唯一的顶级节点**

### 通过树形来实现布局

下面这个页面就是通过树形组合出来的，大体结构是这样：

```
Page
  ├── Toolbar
  │  └─ Form 顶部表单项
  ├── Grid // 用于水平布局
  │  ├─ Panel
  │  │  └─ Tabs
  │  │    └─ Chart
  │  └─ Panel
  │     └─ Chart
  └── CRUD
```

```
/* Detailed source-code truncated for AI context efficiency. */
```

> amis 后续将会实现新的布局模式，将更容易实现复杂布局效果

---

### Zh CN Concepts Style (`docs/zh-CN/concepts/style.md`)

---
title: 样式
description:
type: 0
group: 💡 概念
menuName: 样式
icon:
order: 18
---

amis 中有大量的功能类 class 可以使用，即可以用在 schema 中，也可以用在自定义组件开发中，掌握这些 class, 几乎可以不用写样式。

<div class="bg-pink-500 text-light shadow p-4 rounded-md hover:bg-pink-600">
  <div class="text-lg b-b p-b-sm">注意</div>
  <div class="p-t-xs">CSS辅助类样式做了全新的升级，请点击顶部的「样式」查看新版。旧版本可以继续，但将不再更新。</div>
</div>

## 基本使用

例如，下面这个例子，我们内容区渲染了两个按钮，但是可以看到，两个按钮紧贴在一起，并不是很美观，于是我们想添加一定的间隔

```schema: scope="body"
[
  {
    "type": "button",
    "label": "按钮1",
    "actionType": "dialog",
    "dialog": {
      "title": "弹框",
      "body": "Hello World!"
    }
  },
  {
    "type": "button",
    "label": "按钮2",
    "actionType": "dialog",
    "dialog": {
      "title": "弹框",
      "body": "Hello World!"
    }
  }
]
```

1. 通过查阅按钮文档可知，按钮支持 className 配置项，也就是说可以在按钮上添加 CSS 类名；
2. 再查阅当前页面下面 [外边距部分](#%E5%A4%96%E8%BE%B9%E8%B7%9D) 可知，我们可以添加`m-l`类名实现`margin-left: 15px;`的 CSS 效果
3. 于是我们在`按钮2`的配置中添加`"className": "m-l"`，就能实现间距效果了

```schema: scope="body"
[
  {
    "type": "button",
    "label": "按钮1",
    "actionType": "dialog",
    "dialog": {
      "title": "弹框",
      "body": "Hello World!"
    }
  },
  {
    "type": "button",
    "label": "按钮2",
    "className": "m-l",
    "actionType": "dialog",
    "dialog": {
      "title": "弹框",
      "body": "Hello World!"
    }
  }
]
```

绝大部分组件都支持各种形式的 CSS 类名自定义，然后搭配该文档中的各种类名可以实现各式各样的样式调整。具体请查阅组件文档；

> 你可能需要掌握一些基础的 CSS 知识

## 字体颜色

实际颜色取决于主题，下面示例是默认主题的颜色。

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 图标

amis 集成了 [fontawesome](http://fontawesome.io/icons/)，所以关于图标部分，请前往 [fontawesome](http://fontawesome.io/icons/) 查看。

## 布局

水平布局可以考虑用 Bootstrap 的 [Grids](http://getbootstrap.com/css/#grid) 或者用 `hbox` 加 `col`

```html
<div class="hbox b-a">
  <div class="col wrapper-sm bg-success">Col A</div>
  <div class="col wrapper-sm bg-info">Col B</div>
  <div class="col wrapper-sm bg-danger">Col C</div>
</div>
```

## 宽高

```css

  width: 1em;
}

.w-2x {
  width: 2em;
}

.w-3x {
  width: 3em;
}

.w-xxs {
  width: 60px;
}

.h-xxs {
  height: 60px;
}

.w-xs {
  width: 90px;
}

.h-xs {
  height: 90px;
}

.w-ssm {
  width: 120px;
}

.w-sm {
  width: 150px;
}

.h-sm {
  height: 150px;
}

.h-ssm {
  height: 120px;
}

.w {
  width: 200px;
}

.h {
  height: 200px;
}

.w-md {
  width: 240px;
}

.h-md {
  height: 240px;
}

.w-lg {
  width: 280px;
}

.h-lg {
  height: 280px;
}

.w-xl {
  width: 320px;
}

.h-xl {
  height: 320px;
}

.w-xxl {
  width: 360px;
}

.h-xxl {
  height: 360px;
}

.w-xxxl {
  width: 420px;
}

.h-xxxl {
  height: 420px;
}

.w-full {
  width: 100%;
}

.w-auto {
  width: auto;
}

.h-auto {
  height: auto;
}

.h-full {
  height: 100%;
}
```

```html
<div class="hbox b-a bg-primary">
  <div class="col wrapper-sm b-r w-1x">w-1x</div>
  <div class="col wrapper-sm b-r w-2x">w-2x</div>
  <div class="col wrapper-sm b-r w-3x">w-3x</div>
  <div class="col wrapper-sm b-r w-xxs">w-xxs</div>
  <div class="col wrapper-sm b-r w-xs">w-xs</div>
  <div class="col wrapper-sm b-r w-sm">w-sm</div>
  <div class="col wrapper-sm b-r w">w</div>
  <div class="col wrapper-sm  lter">...</div>
</div>
<div class="hbox b-a bg-primary m-t">
  <div class="col wrapper-sm b-r w-md">w-md</div>
  <div class="col wrapper-sm b-r w-lg">w-lg</div>
  <div class="col wrapper-sm b-r w-xl">w-xl</div>
  <div class="col wrapper-sm lter">...</div>
</div>
<div class="hbox b-a bg-primary m-t">
  <div class="col wrapper-sm b-r w-xxl">w-xxl</div>
  <div class="col wrapper-sm lter">...</div>
</div>
```

## 外边距

```
/* Detailed source-code truncated for AI context efficiency. */
```

## 内边距

```css
.wrapper-xs {
  padding: 5px;
}
.wrapper-sm {
  padding: 10px;
}
.wrapper {
  padding: 15px;
}
.wrapper-md {
  padding: 20px;
}
.wrapper-lg {
  padding: 30px;
}
.wrapper-xl {
  padding: 50px;
}
.padder-xs {
  padding-left: 5px;
  padding-right: 5px;
}
.padder-sm {
  padding-left: 10px;
  padding-right: 10px;
}
.padder-lg {
  padding-left: 30px;
  padding-right: 30px;
}
.padder-md {
  padding-left: 20px;
  padding-right: 20px;
}
.padder {
  padding-left: 15px;
  padding-right: 15px;
}
.padder-v-xs {
  padding-top: 5px;
  padding-bottom: 5px;
}
.padder-v-sm {
  padding-top: 10px;
  padding-bottom: 10px;
}
.padder-v-lg {
  padding-top: 30px;
  padding-bottom: 30px;
}
.padder-v-md {
  padding-top: 20px;
  padding-bottom: 20px;
}
.padder-v {
  padding-top: 15px;
  padding-bottom: 15px;
}
.no-padder {
  padding: 0 !important;
}
.pull-in {
  margin-left: -15px;
  margin-right: -15px;
}
.pull-out {
  margin: -10px -15px;
}
```

## 边框

```css
.b {
  border: 1px solid rgba(0, 0, 0, 0.05);
}
.b-a {
  border: 1px solid @border-color;
}
.b-t {
  border-top: 1px solid @border-color;
}
.b-r {
  border-right: 1px solid @border-color;
}
.b-b {
  border-bottom: 1px solid @border-color;
}
.b-l {
  border-left: 1px solid @border-color;
}
.b-light {
  border-color: @brand-light;
}
.b-dark {
  border-color: @brand-dark;
}
.b-black {
  border-color: @brand-dark;
}
.b-primary {
  border-color: @brand-primary;
}
.b-success {
  border-color: @brand-success;
}
.b-info {
  border-color: @brand-info;
}
.b-warning {
  border-color: @brand-warning;
}
.b-danger {
  border-color: @brand-danger;
}
.b-white {
  border-color: #fff;
}
.b-dashed {
  border-style: dashed !important;
}
.b-l-light {
  border-left-color: @brand-light;
}
.b-l-dark {
  border-left-color: @brand-dark;
}
.b-l-black {
  border-left-color: @brand-dark;
}
.b-l-primary {
  border-left-color: @brand-primary;
}
.b-l-success {
  border-left-color: @brand-success;
}
.b-l-info {
  border-left-color: @brand-info;
}
.b-l-warning {
  border-left-color: @brand-warning;
}
.b-l-danger {
  border-left-color: @brand-danger;
}
.b-l-white {
  border-left-color: #fff;
}
.b-l-2x {
  border-left-width: 2px;
}
.b-l-3x {
  border-left-width: 3px;
}
.b-l-4x {
  border-left-width: 4px;
}
.b-l-5x {
  border-left-width: 5px;
}
.b-2x {
  border-width: 2px;
}
.b-3x {
  border-width: 3px;
}
.b-4x {
  border-width: 4px;
}
.b-5x {
  border-width: 5px;
}
```

## 圆角

```css
.r {
  border-radius: @border-radius-base @border-radius-base @border-radius-base
    @border-radius-base;
}
.r-2x {
  border-radius: @border-radius-base * 2;
}
.r-3x {
  border-radius: @border-radius-base * 3;
}
.r-l {
  border-radius: @border-radius-base 0 0 @border-radius-base;
}
.r-r {
  border-radius: 0 @border-radius-base @border-radius-base 0;
}
.r-t {
  border-radius: @border-radius-base @border-radius-base 0 0;
}
.r-b {
  border-radius: 0 0 @border-radius-base @border-radius-base;
}
```

## 字体相关

```css
.font-normal {
  font-weight: normal;
}
.font-thin {
  font-weight: 300;
}
.font-bold {
  font-weight: 700;
}
.text-3x {
  font-size: 3em;
}
.text-2x {
  font-size: 2em;
}
.text-lg {
  font-size: @font-size-lg;
}
.text-md {
  font-size: @font-size-md;
}
.text-base {
  font-size: @font-size-base;
}
.text-sm {
  font-size: @font-size-sm;
}
.text-xs {
  font-size: @font-size-xs;
}
.text-xxs {
  text-indent: -9999px;
}
.text-ellipsis {
  display: block;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.text-u-c {
  text-transform: uppercase;
}
.text-l-t {
  text-decoration: line-through;
}
.text-u-l {
  text-decoration: underline;
}
.text-left {
  text-align: left;
}
.text-center {
  text-align: center;
}
.text-right {
  text-align: right;
}
.word-break {
  white-space: normal;
  word-break: break-all;
  word-wrap: break-word;
}
.white-space-pre {
  white-space: pre;
}
```

## 定位

```css
.pos-rlt {
  position: relative;
}
.pos-stc {
  position: static !important;
}
.pos-abt {
  position: absolute;
}
.pos-fix {
  position: fixed;
}
```

## 背景

```html
<div class="hbox b-a bg-light">
  <div class="col wrapper-sm b-r bg-white">bg-white</div>
  <div class="col wrapper-sm b-r bg-dark">bg-dark</div>
  <div class="col wrapper-sm b-r bg-info">bg-info</div>
  <div class="col wrapper-sm b-r bg-success">bg-success</div>
  <div class="col wrapper-sm b-r bg-warning">bg-warning</div>
  <div class="col wrapper-sm b-r bg-danger">bg-danger</div>
  <div class="col wrapper-sm bg-primary">bg-primary</div>
</div>
```

## 其他

```css
.show {
  visibility: visible;
}
.line {
  width: 100%;
  height: 2px;
  margin: 10px 0;
  font-size: 0;
  overflow: hidden;
  background-color: transparent;
  border-width: 0;
  border-top: 1px solid @border-color;
}
.line-xs {
  margin: 0;
}
.line-lg {
  margin-top: 15px;
  margin-bottom: 15px;
}
.line-dashed {
  border-style: dashed;
  background: transparent;
}
.no-line {
  border-width: 0;
}
.no-border,
.no-borders {
  border-color: transparent;
  border-width: 0;
}
.no-radius {
  border-radius: 0;
}
.block {
  display: block;
}
.block.hide {
  display: none;
}
.inline {
  display: inline-block !important;
}
.none {
  display: none;
}
.pull-left {
  float: left;
}
.pull-right {
  float: right;
}
.pull-none {
  float: none;
}
.rounded {
  border-radius: 500px;
}
.clear {
  display: block;
  overflow: hidden;
}
.no-bg {
  background-color: transparent;
  color: inherit;
}
.no-select {
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  -khtml-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}
```

---

### Zh CN Concepts Template (`docs/zh-CN/concepts/template.md`)

---
title: 模板
description:
type: 0
group: 💡 概念
menuName: 模板
icon:
order: 11
---

为了可以更加灵活渲染文本、数据结构，amis 借鉴其他模板引擎，实现了一套模板渲染功能。

## 模板字符串

### 普通文本

配置一段普通文本并输出

```schema
{
  "type": "page",
  "body": "Hello World!" // 输出 Hello World!
}
```

### 文本中获取变量

可以支持在普通文本中，使用**数据映射**语法：`${xxx}` 获取数据域中变量的值，如下

```schema
{
  "data": {
    "text": "World!"
  },
  "type": "page",
  "body": "Hello ${text}" // 输出 Hello World!
}
```

更多`${xxx}`语法相关介绍，移步 [数据映射](./data-mapping)。

### 渲染 html

使用**数据映射**语法：`${xxx}` 获取数据域中变量的值，并渲染 HTML

```schema
{
  "data": {
    "text": "World!"
  },
  "type": "page",
  "body": "<h1>Hello</h1> <span>${text}</span>"
}
```

如果是变量本身有 html，则需要使用 raw 过滤

```schema
{
  "data": {
    "text": "<b>World!</b>"
  },
  "type": "page",
  "body": "<h1>Hello</h1> <span>${text|raw}</span>"
}
```

### 表达式

> 1.5.0 及以上版本

支持简单的表达式运算以及公式调用，具体请查看[新表达式语法](./expression#新表达式语法)

```json
{
  "type": "tpl",
  "tpl": "${xxx == 1 ? 'One' : 'Others'}"
}
```

## JavaScript 模板引擎

amis 还支持用 JavaScript 模板引擎进行组织输出，内部采用 [lodash template](https://lodash.com/docs/4.17.15#template) 进行实现。

```schema
{
    "type": "page",
    "data": {
        "user": "no one",
        "items": [
            "A",
            "B",
            "C"
        ]
    },
    "body": [
        {
            "type": "tpl",
            "tpl": "User: <%- data.user %>"
        },
        {
            "type": "divider"
        },
        {
            "type": "tpl",
            "tpl": "<% if (data.items && data.items.length) { %>Array: <% data.items.forEach(function(item) { %> <span class='label label-default'><%- item %></span> <% });} %>"
        }
    ]
}
```

> 注意到了吗？
>
> 在 JavaScript 模板引擎中，我们获取数据域变量的方式是`data.xxx`，而不是之前的`${xxx}`，如果你熟悉 JavaScript 的话，这里模板引擎其实是将数据域，当做当前代码的数据作用域进行执行，因此需要使用`data.xxx`进行取值
>
> 要注意使用模板的时候在不同的场景下要使用正确的取值方式。

仔细看示例不难发现，语法跟 ejs 很像，`<% 这里面是 js 语句 %>`，所以只要会写 js，做页面渲染没有什么问题。另外以下是一些可用 js 方法。

- `formatDate(value, format='LLL', inputFormat='')`格式化时间格式，关于 format 请前往 [moment](https://momentjs.com/docs/) 文档页面。
- `formatTimeStamp(value, format='LLL')` 格式化时间戳为字符串。
- `formatNumber(number)` 格式化数字格式，加上千分位。
- `countDown(value)` 倒计时，显示离指定时间还剩下多少天，只支持时间戳。

下面 filters 中的方法也可以使用如： `<%- date(data.xxx, 'YYYY-MM-DD') %>`

## 注意事项

#### 1. 模板字符串 和 Javascript 模板引擎 不可以交叉使用

例如：

```json
{
  "type": "tpl",
  "tpl": "${data.xxx === 'a'}" //错误！
}
```

```json
{
  "type": "tpl",
  "tpl": "${xxx === 'a'}" // 正确
}
```

---

### Zh CN Extend Addon (`docs/zh-CN/extend/addon.md`)

---
title: 扩展现有组件
---

除了新增组件，在 amis 中还能扩展和修改现有组件。

## 扩展表单验证

如果默认的表单检测规则不满足需求，还可以通过代码的方式扩展。

### 普通用法

JSSDK 中的用法：

```javascript
let amisLib = amisRequire('amis');
amisLib.addRule(
  // 校验名
  'isZXS',
  // 校验函数，values 是表单里所有表单项的值，可用于做联合校验；value 是当前表单项的值
  (values, value) => {
    if (
      value === '北京' ||
      value === '上海' ||
      value === '天津' ||
      value === '重庆'
    ) {
      // return true 表示校验通过
      return true;
    }
    // return false 表示校验不通过，会进行错误提示
    return false;
  },
  // 出错时的报错信息
  '输入的不是直辖市'
);
```

这样在配置中就能使用下面的验证方法

```
"validations": {
  "isZXS": true
}
```

在 React 的使用方法是类似的

```javascript
import {addRule} from 'amis';
```

### 更加灵活的提示错误

> `2.9.1` 及以上版本

如果想在一个验证函数里根据不同情况提示不同的错误信息，需要返回固定格式的结果：

```js
{
  error: true,
  msg: '错误信息'
}
```

注意，当返回对象时，`error`必须为`true` 才会判定为错误：

具体用法如下：

```javascript
let amisLib = amisRequire('amis');
amisLib.addRule(
  // 校验名
  'isZXS',
  // 校验函数，values 是表单里所有表单项的值，可用于做联合校验；value 是当前表单项的值
  (values, value) => {
    if (value === '新加坡') {
      // 校验不通过，提示：该地区不在国内
      return {
        error: true,
        msg: '该地区不在国内'
      };
    }

    if (
      value === '北京' ||
      value === '上海' ||
      value === '天津' ||
      value === '重庆'
    ) {
      // return true 表示校验通过
      return true;
    }

    // 校验不通过，提示：输入的不是直辖市
    return {
      error: true,
      msg: '输入的不是直辖市'
    };
  }
);
```

## 同时支持多种类型编辑

在表单编辑中，每个 name 一般对应一种类型，如果这个 name 有多种类型，比如下面的例子中 id 的值有可能是字符串，也有可能是数字，但 type 只能设置为一种类型，这种情况如何处理？

```schema: scope="body"
{
    "type": "form",
    "mode": "horizontal",
    "body": [
        {
            "name": "id",
            "type": "input-text",
            "label": "id"
        }
    ]
}
```

有两种方式：

### 使用另一个名称作为状态

```schema: scope="body"
{
  "type": "form",
  "mode": "horizontal",
  "body": [
    {
      "name": "idIsNumber",
      "type": "switch",
      "label": "id 是数字类型"
    },
    {
      "name": "id",
      "type": "input-text",
      "label": "id",
      "hiddenOn": "data.idIsNumber"
    },
    {
      "name": "id",
      "type": "input-number",
      "label": "id",
      "visibleOn": "data.idIsNumber"
    }
  ]
}
```

可以看到在一个 form 中可以有两个 name 相同的组件，通过 hiddenOn 或 visibleOn 来控制同时只显示一个。

### 使用 PipeIn/PipeOut 方法

如果不想增加一个新的 name，在 JS SDK 或 React 还有更高级的处理方法，可以增加一个 name 同样为 id 的 switch，实现 PipeIn/PipeOut 函数来进行自动识别，下面是个示例：

```javascript
let amis = amisRequire('amis/embed');
let amisScoped = amis.embed('#root', {
  type: 'page',
  title: '表单页面',
  // 可以通过去掉下面的注释来测试
  // data: {
  //   id: 1
  // },
  body: {
    type: 'form',
    mode: 'horizontal',
    api: '/saveForm',
    body: [
      {
        type: 'switch',
        label: 'id 是数字',
        name: 'id',
        // pipeIn 返回的应该是这个组件所需的值，比如 switch 的返回值就应该是 true 或 false
        // 这里的 value 就是初始值，如果不设置将会是 undefined
        pipeIn: (value, data) => {
          if (typeof value === 'undefined') {
            return false;
          }
          return typeof value !== 'string';
        },
        // 这里的 value 是点击 switch 之后的值，比如打开就是 true，关闭就是 false
        pipeOut: (value, oldValue, data) => {
          if (value) {
            return 1; // 切换到数字之后的默认值
          } else {
            return 'id1'; // 关闭之后的默认值
          }
        }
      },
      {
        name: 'id',
        type: 'text',
        label: 'id',
        visibleOn:
          'typeof data.id === "undefined" || typeof data.id === "string"'
      },
      {
        name: 'id',
        type: 'number',
        label: 'id',
        visibleOn: 'typeof data.id === "number"'
      }
    ]
  }
});
```

不过这种写法的复杂度较高

## 修改组件标签

有些组件可以设置 `wrapperComponent`，比如 Form 下默认使用 form 标签，在浏览器中会自带回车提交功能，如果想去掉这个功能，可以将 `wrapperComponent` 设置为 `div`。

---

### Zh CN Extend Contribute (`docs/zh-CN/extend/contribute.md`)

---
title: 如何贡献代码
---

如果发现 amis 有不满足的功能，除了发 issue 等官方升级之外，最快的方法就是自己实现它，本文将介绍 amis 代码的基本结构，并一步步教你如何新增功能。

## 准备开始

1. 首先，你需要对 React 有基本了解，快速看一遍[官方文档](https://zh-hans.react.dev/learn)即可。
2. 在 github 上 fork amis 项目到自己的账号下。
3. 创建分支 `git checkout -b feat-xxx`

## amis 代码结构

amis 主要代码在 `src` 和 `scss` 目录下，这里主要介绍 `src` 下的结构：

```
.
├── Root.tsx            // amis 最外层的渲染组件
├── RootRenderer.tsx    // 用于 Root.tsx，拆分一下避免文件太大
├── Schema.ts           // 基础类型定义
├── SchemaRenderer.tsx  // amis 组件渲染的主要入口
├── Scoped.tsx          // 数据域的实现
├── WithRootStore.tsx   // 用于表单项中注入 root context
├── WithStore.tsx       // 用于表单项中的数据存储及同步
├── compat.ts           // 用于兼容旧版的配置，比如将 1.1.x 的配置转成 1.2.x
├── components          // 大部分组件的实现在这里，也有很多内部使用的公共组件，这里的组件也能被其他 React 组件使用
├── env.tsx             // 默认的 env，env 可以由外部传入，比如最常见的是 fetcher，这样就能自己接管网络请求，比如使用客户端中的网络请求方法
├── envOverwrite.ts     // 用于在移动端或不同语言环境下使用不同配置
├── factory.tsx         // amis 渲染的总入口，对外暴露的 render 方法就在这里
├── icons               // 内置的 icon
├── index.tsx           // amis 项目对外的主要入口
├── locale              // 多语言翻译，目前只有英文和德语
├── locale.tsx          // 多语言支持的实现
├── renderers           // 将组件注册到 amis 渲染器中，这里大部分组件是直接引用 components 里的对应组件，也有部分简单的组件是直接在这里实现，
├── store               // mst 存储
├── theme.tsx           // 主题相关的实现
├── themes              // 主题配置，有些主题效果不太好通过 css 实现，就放这了
├── types.ts            // 一些公共的类型定义
└── utils               // amis 内部用的常用工具方法
```

虽然文件很多，但对于组件开发而言，大部分情况下只需要关注 `components` 及 `renderers` 目录下的内容就行，如果发现某个组件不满足需求，可以先在 `renderers` 中找到这个组件，对齐进行修改就行。

下面我们将以一个实际例子来介绍如何新增一个组件。

## 实战：avatar 组件

本文的目标是新增 avatar 头像组件，完整演示如何在 amis 中添加一个新组件，完整实现可以参考这个 [pr](https://github.com/baidu/amis/pull/1684/files)，本文基于这个例子进行了简化。

### 编写 React 组件代码代码

由于这个组件并不需要被其他组件复用，所以只需要在 `renderers` 目录下实现就好，整体步骤是：

新增 `src/renderers/Avatar.tsx` 文件，内容如下

```tsx
import React from 'react';
import {Renderer, RendererProps, AMISSchemaBase} from 'amis-core';
import {resolveVariable, resolveVariableAndFilter} from 'amis-core';

// schema 是用来给编辑器提示用的，同时也作为组件 props 的类型定义
export interface AvatarSchema extends AMISSchemaBase {
  // 定义类型
  type: 'avatar';

  // 下面都是这个组件的其他属性参数，这里定义了一个 src
  src?: string;
}

// 大部分组件都是直接继承 RendererProps，里面包含渲染组件所需的常用属性
export interface AvatarProps
  extends RendererProps,
    Omit<AvatarSchema, 'type' | 'className'> {}

// 这个是组件的实现部分
export class AvatarField extends React.Component<AvatarProps, object> {
  render() {
    let {className, src, classnames: cx} = this.props;

    // 所有组件的 classname 都需要使用 cx 函数，并且以大写开头，这是为了方便支持多主题
    return (
      <div className={cx('Avatar', className)}>
        <img src={src} />
      </div>
    );
  }
}

// 将组件注册到 amis 渲染器中
@Renderer({
  type: 'avatar'
})
export class AvatarFieldRenderer extends AvatarField {}
```

上面这段代码中，最核心的就是 `AvatarField`，这就是一个 React 组件。

接下来还需要改两处地方：

- 一个是 `src/Schema.ts`，需要在 `SchemaType` 里加入刚才定义的 `avatar`。
- 另一个是 `src/index.tsx`，增加一行 `import './renders/Avatar';`。

这样就在 amis 中新增了一个组件，接下来我们编写组件所需的样式。

### 编写 SCSS 代码

新组件一般都需要对应的样式，首先创建 `scss/components/_avatar.scss` 文件，内容是：

```css
// 注意必须有这个 #{$ns}，它是为了方便生成主题，比如在 cxd 主题下，会转成 `.cxd-Avatar`
.#{$ns}Avatar {
}
```

然后修改 `scss/themes/_common.scss`，通过 `@import '../components/avatar';` 引入这个新文件。

amis 中的 css 命名使用 [SUIT](https://github.com/suitcss/suit/blob/master/doc/naming-conventions.md) 规范，请按照这个规范编写。

如果样式在不同主题下有区别，则需要使用 CSS 变量，在 `scss/_properties.scss` 里定义这个变量的默认值，让后在对应的主题文件中覆盖，比如 `scss/themes/_cxd-variables.scss`。

### 编写文档

新组件还需要有对应的文档来方便其他人了解和使用，首先在 `docs/zh-CN/components/avatar.md` 中创建文件，然后在 `examples/components/Components.tsx` 里引用。

文档编写可以参考其他示例，需要演示这个组件的所有功能。

## 提交 PR

使用 `git push --set-upstream origin feat-xxx` 创建远程分支。

然后通过系统提示的 `https://github.com/xxx/amis/pull/new/feat-xxx` 链接来创建 PR，官方团队会在一个工作日左右回复。

---

--- METRICS ---
- Files Extracted: 100
- Estimated Token Budget: ~279677 tokens
- Canonical Reference: https://codewiki.google/github.com/baidu/amis
