---
title: CRUD 增删改查
description:
type: 0
group: ⚙ 组件
menuName: CRUD 增删改查
icon:
order: 25
---
CRUD,即增删改查组件,主要用来展现数据列表,并支持各类【增】【删】【改】【查】等操作。
注意 CRUD 所需的数据必须放 items 中,因此如果只是想显示表格类型的数据没有分页,请使用 [Table](./table)。
## 基本用法
最基本的用法是配置 **数据源接口(api)** 以及 **展示列(columns)**
```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"
},
{
"name": "grade",
"label": "CSS grade"
},
{
"type": "operation",
"label": "操作",
"buttons": [
{
"label": "详情",
"type": "button",
"level": "link",
"actionType": "dialog",
"dialog": {
"title": "查看详情",
"body": {
"type": "form",
"body": [
{
"type": "input-text",
"name": "engine",
"label": "Engine"
},
{
"type": "input-text",
"name": "browser",
"label": "Browser"
},
{
"type": "input-text",
"name": "platform",
"label": "platform"
},
{
"type": "input-text",
"name": "version",
"label": "version"
},
{
"type": "control",
"label": "grade",
"body": {
"type": "tag",
"label": "${grade}",
"displayMode": "normal",
"color": "active"
}
}
]
}
}
},
{
"label": "删除",
"type": "button",
"level": "link",
"className": "text-danger",
"disabledOn": "this.grade === 'A'"
}
]
}
]
}
```
## 数据源接口数据结构要求
- `items`或`rows`:用于返回数据源数据,格式是数组
- `total`: 用于返回数据库中一共有多少条数据,用于生成分页
```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` 参数。
> 如果 api 地址中有变量,比如 `/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 刷新如:
```schema: scope="body"
[
{
"label": "新增",
"type": "button",
"actionType": "dialog",
"level": "primary",
"className": "m-b-sm",
"dialog": {
"title": "新增表单",
"body": {
"type": "form",
"api": "post:/api/mock2/sample",
"body": [
{
"type": "input-text",
"name": "engine",
"label": "Engine"
},
{
"type": "input-text",
"name": "browser",
"label": "Browser"
}
]
}
}
},
{
"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"
},
{
"name": "platform",
"label": "Platform(s)"
},
{
"name": "version",
"label": "Engine version"
},
{
"name": "grade",
"label": "CSS grade"
}
]
}
]
```
当然如果你不想要自动刷新,那么给按钮配置 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,按钮类型改成弹框。
```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": "drawer",
"drawer": {
"title": "新增表单",
"body": {
"type": "form",
"initApi": "/api/mock2/sample/${id}",
"api": "post:/api/mock2/sample/${id}",
"body": [
{
"type": "input-text",
"name": "engine",
"label": "Engine"
},
{
"type": "input-text",
"name": "browser",
"label": "Browser"
}
]
}
}
}
]
}
]
}
```
弹框里面可用数据自动就是点击的那一行的行数据,如果列表没有返回,可以在 form 里面再配置个 initApi 初始化数据,如果行数据里面有倒是不需要再拉取了。表单项的 name 跟数据 key 对应上便自动回显了。默认发送给表单的保存接口只会包含配置了的表单项,如果不够,请在 api 上配置数据映射,或者直接添加 hidden 类型的表单项(即隐藏域 input[type=hidden])。
### 查
查,就不单独介绍了,这个文档绝大部分都是关于查的。
## 展示模式
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",
"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) 中的所有功能。
```schema: scope="body"
{
"type": "crud",
"api": "/api/mock2/crud/users",
"syncLocation": false,
"mode": "cards",
"defaultParams": {
"perPage": 6
},
"switchPerPage": false,
"placeholder": "没有用户信息",
"columnsCount": 2,
"card": {
"header": {
"className": "bg-white",
"title": "$name",
"subTitle": "$realName",
"description": "$email",
"avatar": "${avatar | raw}",
"highlight": "$isSuperAdmin",
"avatarClassName": "pull-left thumb-md avatar b-3x m-r"
},
"bodyClassName": "padder",
"body": "\n <% if (this.roles && this.roles.length) { %>\n <% this.roles.map(function(role) { %>\n <%- role.name %>\n <% }) %>\n <% } else { %>\n
没有分配角色
\n <% } %>\n ",
"actions": [
{
"label": "编辑",
"actionType": "dialog",
"dialog": {
"title": null,
"body": {
"api": "",
"type": "form",
"tabs": [
{
"title": "基本信息",
"body": [
{
"type": "hidden",
"name": "id"
},
{
"name": "name",
"label": "帐号",
"disabled": true,
"type": "input-text"
},
{
"type": "divider"
},
{
"name": "email",
"label": "邮箱",
"type": "input-text",
"disabled": true
},
{
"type": "divider"
},
{
"name": "isAmisOwner",
"label": "管理员",
"description": "设置是否为超级管理",
"type": "switch"
}
]
},
{
"title": "角色信息",
"body": []
},
{
"title": "设置权限",
"body": []
}
]
}
}
},
{
"label": "移除",
"confirmText": "您确定要移除该用户?",
"actionType": "ajax",
"api": "delete:/api/mock2/notFound"
}
]
}
}
```
## 查询条件表单
大部分表格展示有对数据进行检索的需求,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`列)。
```schema: scope="body"
{
"type": "crud",
"name": "crud",
"syncLocation": false,
"api": "/api/mock2/crud/table4",
"filter": {
"debug": true,
"title": "条件搜索",
"body": [
{
"type": "group",
"body": [
{
"type": "input-text",
"name": "keywords",
"label": "关键字",
"clearable": true,
"placeholder": "通过关键字搜索",
"size": "sm"
},
{
"type": "input-text",
"name": "engine",
"label": "Engine",
"clearable": true,
"size": "sm"
},
{
"type": "input-text",
"name": "platform",
"label": "Platform",
"clearable": true,
"size": "sm"
}
]
}
],
actions: [
{
"type": "button",
"actionType": "drawer",
"icon": "fa fa-plus",
"label": "创建记录",
"target": "crud",
"closeOnOutside": true,
"drawer": {
"title": "创建记录",
"body": {
"type": "form",
"api": "post:/api/mock2/sample",
"body": [
{
"type": "input-text",
"name": "engine",
"label": "Engine"
},
{
"type": "input-text",
"name": "browser",
"label": "Browser"
}
]
}
}
},
{
"type": "reset",
"label": "重置"
},
{
"type": "submit",
"level": "primary",
"label": "查询"
}
]
},
"columns": [
{
"name": "id",
"label": "ID"
},
{
"name": "engine",
"label": "Rendering engine"
},
{
"name": "browser",
"label": "Browser"
},
{
"name": "platform",
"label": "Platform(s)",
"canAccessSuperData": false
},
{
"name": "version",
"label": "Engine version"
},
{
"name": "grade",
"label": "CSS grade"
}
]
}
```
**请注意**:在默认没有自定义配置 api 数据映射时,提交查询条件表单,会自动将表单中的表单项值,发送给`crud`所配置的接口,然后通过后端接口,实现对数据的过滤操作,前端默认是不会进行任何的数据过滤操作
如果想前端实现过滤功能,请看[前端一次性加载](#前端一次性加载)部分。
### 自动生成查询区域
通过设置`"autoGenerateFilter": true`开启查询区域,会根据列元素的 `searchable` 属性值,自动生成查询条件表单,只有 `searchable` 属性值为合法的组件 Schema 时才会生成查询条件。注意这个属性和 `filter` 冲突,开启 `filter` 后 `autoGenerateFilter` 将会失效。
```schema: scope="body"
{
"type": "crud",
"api": "/api/mock2/sample",
"syncLocation": false,
"autoGenerateFilter": true,
"headerToolbar": [
{
"type": "columns-toggler",
"align": "right",
"draggable": true,
"icon": "fas fa-cog",
"overlay": true,
"footerBtnSize": "sm"
}
],
"columns": [
{
"name": "id",
"label": "ID",
"searchable": {
"type": "input-text",
"name": "id",
"label": "主键",
"placeholder": "输入id"
}
},
{
"name": "engine",
"label": "Rendering engine"
},
{
"name": "browser",
"label": "Browser",
"searchable": {
"type": "select",
"name": "browser",
"label": "浏览器",
"placeholder": "选择浏览器",
"options": [
{
"label": "Internet Explorer ",
"value": "ie"
},
{
"label": "AOL browser",
"value": "aol"
},
{
"label": "Firefox",
"value": "firefox"
}
]
}
},
{
"name": "platform",
"label": "Platform(s)"
},
{
"name": "version",
"label": "Engine version",
"searchable": {
"type": "input-number",
"name": "version",
"label": "版本号",
"placeholder": "输入版本号",
"mode": "horizontal"
}
},
{
"name": "grade",
"label": "CSS grade"
}
]
}
```
## 配置默认请求参数
可以配置`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`,该列表头右侧会渲染一个可点击的排序图标,可以切换`正序`和`倒序`。
```schema: scope="body"
{
"type": "crud",
"syncLocation": false,
"api": "/api/mock2/sample",
"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
}
]
}
```
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"
]
}
}
]
}
```
amis 只负责生成下拉选择器组件,并将搜索参数传递给接口,而不会在前端对数据进行搜索处理。参数格式如下:
```json
{
"grade": "xxx" // 这里的key是列的 name,value是选中项的value值
}
```
你可以通过[数据映射](../../docs/concepts/data-mapping),在`api`中获取这些参数。
### 快速编辑
可以通过给列配置:`"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
}
}
]
}
```
你也可以在`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 会在配置分页组件的地方,渲染出一个简单的页面跳转控件。
> 如果总数据只够展示一页,则默认不显示该分页组件
### 批量操作
在`headerToolbar`或者`footerToolbar`数组中添加`bulkActions`字符串,并且在 crud 上配置`bulkActions`行为按钮数组,可以实现选中表格项并批量操作的功能。
> 需要设置`primaryField`用于标识选中状态,配置当前行数据中的某一**唯一标识字段**,例如`id`,否则可能会出现无法选中的问题
```schema: scope="body"
{
"type": "crud",
"syncLocation": false,
"api": "/api/mock2/sample",
"headerToolbar": [
"bulkActions"
],
"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"
}
]
}
```
批量操作会默认将下面数据添加到数据域中以供按钮行为使用
- `items` `Array