简体中文
list.render.before
约 4288 字大约 14 分钟
2025-12-16
该钩子在渲染对象表格之前调用。
用途
列表渲染前执行额外的动作,包含且不限于以下功能:
- 自定义对象表格字段展示
- 自定义筛选器
参数
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---|---|---|---|---|
| 通用参数 | 详见 | Object | — | — |
Hook函数入参
functional用于注册Hook回调函数。执行该Hook时,宿主会向回调函数传入以下参数:
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| context | 列表插件上下文,包含通用参数和本事件参数 | Object | -- |
| plugin | 当前插件运行信息,业务逻辑通常不需要使用 | Object | -- |
| context.recordType | 当前业务类型apiName;未指定业务类型时可能为空字符串 | String | -- |
返回结果
Hook可以返回以下配置对象;async Hook也可以返回Promise<Object>。
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| columnsExtendConfig | 列扩展配置 | Object | -- |
| filterExtendConfig | 筛选扩展配置 | Object | -- |
| termExtendConfig | 场景扩展配置 | Object | -- |
| imageExtendConfig | 图片字段扩展配置 | Object | -- |
| viewInfoExtendConfig | 视图扩展配置 | Object | -- |
| actionExtendConfig | 按钮执行行为扩展配置 | Object | -- |
| formatListDataAsync | 处理默认格式化后的列表数据 | Function | -- |
| formatRequestParam | 扩展列表查询请求参数 | Function | -- |
| forceTrWrap | 列表单元格是否强制换行显示 | Boolean | -- |
| allSummaryFields | 按场景配置列表页所有页汇总统计字段 | Object | -- |
| summaryFields | 按场景配置列表页当前页汇总统计字段 | Object | -- |
| enableLiveFiltering | 列表筛选是否启用实时搜索 | Boolean | -- |
| buttons | 列表工具栏按钮配置 | Object | -- |
| operateBtns | 行操作按钮扩展函数数组 | Function[] | -- |
| disableFeatures | 禁用表格指定功能 | Object | -- |
返回对象的顶层属性均为可选,只需返回本次需要修改的配置。
跨对象筛选模式不支持filterExtendConfig、termExtendConfig、viewInfoExtendConfig、disableFeatures和formatRequestParam,宿主会移除这些返回项。
columnsExtendConfig
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| filterColumns | 过滤表格展示的字段,同时影响表格设置和筛选 | Array | -- |
| render | 单元格自定义渲染配置 | Object | -- |
| attrs | 单元格属性扩展配置 | Object | -- |
columnsExtendConfig.render
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| [ fieldApiName ] | 字段渲染函数 | Function | -- |
字段渲染函数签名为render(value, type, data, index)。宿主会将该函数直接作为表格列的渲染函数调用。
| 参数 | 说明 | 类型 |
|---|---|---|
| value | 当前单元格未经默认格式化的原始字段值 | Any |
| type | 当前渲染类型;首次渲染时通常为column,局部更新时可能为当前列配置对象 | String | Object |
| data | 当前行完整数据 | Object |
| index | 当前行在本页数据中的索引 | Number |
返回值会作为单元格内容插入,推荐返回String;字符串中的HTML会按单元格内容渲染。
data中的字段值是未格式化的原始数据。如果将原始字符串拼接到返回的HTML中,必须先进行HTML转义,避免XSS风险。
columnsExtendConfig.attrs
attrs的key可以是字段apiName,也可以是字段的returnType或dataType。字段apiName配置优先。
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| showLookupText | lookup字段是否只显示文本、不可点击 | Boolean | -- |
| isEdit | 是否允许单元格编辑 | Boolean | -- |
| noSupportBatchEdit | 是否禁用批量编辑 | Boolean | -- |
| disabledDel | 是否禁用该字段单元格的清除值操作 | Boolean | -- |
| fixed | 是否将列固定在表格左侧 | Boolean | -- |
filterExtendConfig
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| [ fieldApiName ] | 字段的筛选配置 | Object | -- |
filterExtendConfig.
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| disabled | 禁用筛选功能(即该字段不支持筛选) | Boolean | -- |
| onlyOr | 需保留的操作符 | Array | -- |
| components | 不同操作符对应的筛选字段组件 | Object | -- |
| filterOptions | 过滤单选字段/多选字段类型的选项 | Function | -- |
| defaultCompare | 默认操作符 | Number | -- |
| selectType | 单选或多选字段的筛选组件展示类型;select表示强制使用下拉选择器 | String | -- |
| groupIncludeChildrenStatus | 部门筛选是否包含子部门;2表示包含,1表示不包含 | Number | -- |
onlyOr、defaultCompare和components使用相同的操作符编号。常用编号如下,字段实际支持的操作符取决于字段类型:
| 编号 | 操作符 | 说明 |
|---|---|---|
| 1 | EQ | 等于 |
| 2 | N | 不等于 |
| 3 | GT | 大于 |
| 4 | GTE | 大于等于 |
| 5 | LT | 小于 |
| 6 | LTE | 小于等于 |
| 7 | LIKE | 包含 |
| 8 | NLIKE | 不包含 |
| 9 | IS | 为空 |
| 10 | ISN | 不为空 |
| 11 | STARTWITH | 起始于 |
| 12 | ENDWITH | 结束于 |
| 13 | HASANYOF | 属于 |
| 14 | NHASANYOF | 不属于 |
| 17 | BETWEEN | 时间段 |
| 22 | IN | 文本类型属于 |
| 23 | NIN | 文本类型不属于 |
filterOptions函数签名为filterOptions(options):
| 参数 | 说明 | 类型 |
|---|---|---|
| options | 当前字段原始选项数组 | Object[] |
options数组项常用字段:
| 参数 | 说明 | 类型 |
|---|---|---|
| value | 选项内部值 | Any |
| label | 选项显示名称 | String |
必须返回过滤后的选项数组Object[],返回值会直接替换当前字段的筛选选项。
components是以操作符编号comparison为key、筛选组件构造函数为value的对象。宿主通过new components[comparison](options)创建组件。条件筛选器中的组件实例需要实现render()、getValue()和destroy();用于外置筛选器时还需要实现setValue()和clean()。
筛选组件方法:
| 方法 | 说明 | 返回值 |
|---|---|---|
| render(container: HTMLElement) | 将组件渲染到宿主提供的原生DOM容器 | void |
| getValue() | 返回当前筛选值 | Any |
| destroy() | 销毁组件并清理DOM和事件 | void |
| setValue(value) | 设置筛选值,外置筛选器需要实现 | void |
| clean() | 清空筛选值,外置筛选器需要实现 | void |
筛选组件构造函数的options参数:
| 参数 | 说明 | 类型 |
|---|---|---|
| fieldAttr | 当前筛选字段描述 | Object |
| filterValue | 当前筛选值 | Any |
| model | 当前筛选条件的数据模型 | Object |
| search | 触发当前筛选查询的无参函数 | () => void |
| $el | 条件筛选器提供的jQuery挂载容器 | jQuery |
| zIndex | 条件筛选器浮层的z-index | Number |
| keyEnterFn | 条件筛选器的回车查询无参函数,与search行为一致 | () => void |
| el | 外置筛选器提供的jQuery挂载容器 | jQuery |
条件筛选器传入$el、zIndex和keyEnterFn;外置筛选器传入el。组件应使用当前场景实际收到的容器参数,不要假定两者同时存在。
termExtendConfig
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| default | 默认展示的场景,需要传筛选场景apiName | String | -- |
| retain | 需保留的场景,需要传筛选场景apiName或ID | Array | -- |
imageExtendConfig
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| [ imageFieldApiName ] | 图片字段的相关配置 | Object | -- |
imageExtendConfig.
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| previewWidth | 图片悬停预览宽度 | Number | -- |
| previewHeight | 图片悬停预览高度 | Number | -- |
actionExtendConfig
actionExtendConfig的key是按钮执行时的运行时action,严格区分大小写。该值不一定与布局按钮的action或api_name相同,不能直接混用。例如,内置新建按钮在布局中的action为Add,执行时会转换为运行时action add,因此应配置actionExtendConfig.add。
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| [action] | 按按钮action配置执行参数或行操作前置逻辑 | Object | -- |
| beforeRowAction | 所有行操作共用的前置Hook;对应action没有提供该Hook时作为兜底 | (params: Object) => Promise | -- |
actionExtendConfig.
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| parseParam | 扩展按钮执行参数 | (params: Object) => Object | -- |
| beforeRowAction | 行操作执行前Hook,返回Promise | (params: Object) => Promise | -- |
parseParam(params)接收按钮的完整执行参数,返回需要新增或覆盖的参数对象,返回结果会浅合并到原参数中。
工具栏按钮parseParam(params)的params参数:
| 参数 | 说明 | 类型 |
|---|---|---|
| source | 操作来源,列表页固定为list | String |
| apiname | 当前对象apiName | String |
| pageApiname | 当前页面对象apiName | String |
| dataList | 当前选中或待操作的行数据 | Object[] |
| queryParam | 当前列表查询参数 | Object |
| recordType | 当前业务类型apiName | String |
| displayName | 当前对象显示名称 | String |
| describe | 当前对象描述 | Object |
| field_list | 列表当前字段apiName数组 | String[] |
| _show_field_list | 列表当前展示的列配置 | Object[] |
| objectDescribeExt | 当前对象扩展描述 | Object |
| success | 默认操作成功后刷新列表的函数 | Function |
按钮自身的执行参数也会合并到params中。
beforeRowAction(params)接收行操作按钮的完整执行参数,必须返回Promise。Promise resolve后继续执行默认按钮逻辑;Promise reject时不会继续执行默认按钮逻辑。
行操作按钮params常用字段如下:
| 参数 | 说明 | 类型 |
|---|---|---|
| data | 当前行完整数据 | Object |
| dataId | 当前数据ID | String |
| fields | 按钮参数表单的字段配置 | Object[] |
| title | 按钮显示名称 | String |
| apiname | 当前行对象apiName | String |
| button_apiname | 按钮apiName | String |
| button_action | 按钮action | String |
| button_type | 按钮类型 | String |
| redirect_type | 按钮跳转类型 | String |
| buttonInfo | 完整按钮描述 | Object |
| objectDescribe | 当前对象描述 | Object |
| objectDescribeExt | 当前对象扩展描述 | Object |
| shouldFetchDetail | 是否需要查询详情;Edit操作为true | Boolean |
| _from | 操作来源,可能为list或relatedList | String |
| success | 默认操作成功后刷新列表的函数 | Function |
formatListDataAsync
函数签名为formatListDataAsync(listData)。
| 参数 | 说明 | 类型 |
|---|---|---|
| listData | 标准列表格式化后的数据,结构为{ totalCount, data } | Object |
| listData.totalCount | 列表数据总数 | Number |
| listData.data | 当前页行数据 | Object[] |
返回值必须保持{ totalCount, data }结构,可以直接返回对象,也可以返回Promise<Object>。
const formatListDataAsync = (listData) => ({
...listData,
data: listData.data.map(rowData => ({
...rowData,
pluginProcessed: true
}))
});formatRequestParam
函数签名为formatRequestParam(params)。
| 参数 | 说明 | 类型 |
|---|---|---|
| params | 对象列表查询接口的完整请求参数 | Object |
| params.object_describe_api_name | 当前对象apiName | String |
| params.search_template_id | 当前筛选场景ID | String |
| params.search_query_info | JSON字符串,包含limit、offset、filters、orders等查询信息 | String |
返回值类型为Object | void。返回Object时会浅合并到原params中;也可以直接修改params并不返回值,推荐返回明确的变更对象,使生成代码的行为更清晰。
disableFeatures
disableFeatures中所有属性均为可选,值为true时禁用对应功能:
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| term | 禁用场景切换 | Boolean | -- |
| allowTerm | 移除场景数据 | Boolean | -- |
| filter | 禁用筛选 | Boolean | -- |
| sort | 禁用字段排序 | Boolean | -- |
| multiSort | 禁用多字段排序 | Boolean | -- |
| search | 禁用搜索 | Boolean | -- |
| quickFilter | 禁用快捷筛选 | Boolean | -- |
| button | 隐藏通用按钮 | Boolean | -- |
| batchButtons | 隐藏批量操作按钮 | Boolean | -- |
| operate | 禁用单行操作按钮 | Boolean | -- |
| multiple | 禁用多选 | Boolean | -- |
| termBatch | 隐藏场景批量区域 | Boolean | -- |
| recordType | 禁用业务类型 | Boolean | -- |
| view | 禁用视图切换 | Boolean | -- |
| refresh | 禁用刷新 | Boolean | -- |
| setting | 隐藏设置 | Boolean | -- |
| summary | 隐藏汇总信息 | Boolean | -- |
| pagination | 禁用分页 | Boolean | -- |
| tag | 隐藏标签按钮 | Boolean | -- |
| guide | 禁用列表引导 | Boolean | -- |
| detail | 禁用进入详情 | Boolean | -- |
allSummaryFields
allSummaryFields是以筛选场景ID或场景apiName为key的对象,value为以下汇总字段数组。仅当前场景匹配对应key时生效。
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| type | 固定值sum | String | -- |
| field_name | 字段apiName | String | -- |
| api_name | 由type和field_name拼接而成,例如sum_amount__c | String | -- |
summaryFields
summaryFields是以筛选场景ID或场景apiName为key的对象,value为以下汇总字段数组。仅当前场景匹配对应key时生效。
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| type | 固定值sum | String | -- |
| field_name | 字段apiName | String | -- |
buttons|operateBtns
buttons用于配置列表工具栏按钮:
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| add | 添加自定义按钮 | Object[] | -- |
| del | 删除指定按钮,数组项为按钮action或apiName | String[] | -- |
| reset | 重置已有按钮名称或行为 | Object[] | -- |
buttons.add数组项参数:
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| action | 自定义按钮唯一action;与已有按钮重复时不会添加 | String | -- |
| label | 按钮显示名称 | String | -- |
| exposed | 是否外露显示 | Boolean | false |
| callback | 点击回调,签名为callback(params) | Function | -- |
| placement | 插入位置,结构为{ base, relative } | Object | -- |
| placement.base | 作为定位基准的已有按钮action或apiName | String | -- |
| placement.relative | next表示插入基准按钮之后,其他值表示之前 | String | -- |
buttons.add中action和label为必填项;需要按钮响应点击时还必须提供callback。
工具栏按钮callback(params)的params参数:
| 参数 | 说明 | 类型 |
|---|---|---|
| recordType | 当前业务类型apiName | String |
| objectApiName | 当前对象apiName | String |
buttons.reset数组项使用action定位已有按钮,可以通过label修改名称,通过callback(params)替换点击行为。
buttons.del、buttons.reset[].action和buttons.add[].placement.base均在运行时action转换前定位布局按钮,应使用布局按钮原始的action或api_name。例如,定位内置新建按钮时使用Add,而扩展其执行参数时使用actionExtendConfig.add。
operateBtns必须是函数数组Array<(rowData: Object) => Object>。每个函数在处理一行数据时执行,入参rowData为当前行完整数据,返回以下配置:
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| add | 添加当前行自定义按钮 | Object[] | -- |
| del | 删除指定行按钮,数组项为按钮action | String[] | -- |
| reset | 以按钮action为key,重置按钮名称或回调 | Object | -- |
| retain | 仅保留指定action的行按钮 | String[] | -- |
operateBtns.add和operateBtns.reset中的自定义按钮callback(params)接收行操作按钮完整执行参数。
operateBtns.add数组项参数:
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| action | 自定义行操作按钮的唯一action | String | -- |
| label | 按钮显示名称 | String | -- |
| callback | 点击回调,签名为callback(params) | Function | -- |
operateBtns.add中action、label和callback为生成可操作行按钮所需的最小字段。
operateBtns.reset[action]使用action定位已有按钮,value可以通过label修改名称,通过callback(params)替换点击行为。
基础示例
扩展列表查询请求参数
export default class Plugin {
apply() {
return [{
event: "list.render.before",
functional: this.renderBefore.bind(this)
}];
}
renderBefore() {
const formatRequestParam = (data) => {
const search_query_info = JSON.parse(data.search_query_info);
if (!search_query_info.filters) {
search_query_info.filters = [];
}
// 追加自定义的筛选条件
search_query_info.filters.push({
field_name: 'name',
field_values: ['value'],
operator: 'LIKE'
})
data.search_query_info = JSON.stringify(search_query_info);
return data;
};
return Promise.resolve({
formatRequestParam
})
}
}控制列表不显示某列数据
export default class Plugin {
apply() {
return [{
event: "list.render.before",
functional: this.renderBefore.bind(this)
}];
}
renderBefore() {
return Promise.resolve({
columnsExtendConfig: {
filterColumns: ['name'], // 过滤主属性字段,使列表不显示主属性列
}
})
}
}自定义某一列单元格显示内容
export default class Plugin {
apply() {
return [{
event: "list.render.before",
functional: this.renderBefore.bind(this)
}];
}
renderBefore() {
return Promise.resolve({
columnsExtendConfig: {
render: {
// 自定义负责人列的显示内容
owner: (value, type, data, index) => {
return `${index + 1}. 自定义负责人`;
}
}
}
})
}
}字段不支持筛选
export default class Plugin {
apply() {
return [{
event: "list.render.before",
functional: this.renderBefore.bind(this)
}];
}
renderBefore() {
return Promise.resolve({
filterExtendConfig: {
name: {
disabled: true //主属性不支持筛选
},
field_0N8Yi__c: {
disabled: true //主属性不支持筛选
}
}
});
}
}过滤筛选器中某个字段支持的操作符
export default class Plugin {
apply() {
return [{
event: "list.render.before",
functional: this.renderBefore.bind(this)
}];
}
renderBefore() {
return Promise.resolve({
filterExtendConfig: {
name: {
onlyOr: [1, 3] // 需保留的操作符
}
}
});
}
}自定义列表筛选器中操作符对应的筛选字段
以下示例使用插件运行环境提供的全局Vue 2对象,包括Vue.extend()、$mount()和$destroy()。
selectfield.vue
<template>
<fx-input v-model="value"></fx-input>
</template>
<script>
export default {
data(){
return {
value: ''
}
}
}
</script>plugin.js
import SelectFieldOptions from "./selectfield.vue";
const SelectField = Vue.extend(SelectFieldOptions);
class FilterComp {
constructor(options){
this.options = options;
this.vm = new SelectField({});
this.vm.value = options.filterValue == null ? '' : options.filterValue;
}
// 宿主渲染筛选器时会传入DOM挂载容器
render(container){
if (!container) {
throw new Error('FilterComp需要有效的DOM挂载容器');
}
this.vm.$mount();
container.appendChild(this.vm.$el);
}
// 表格设置默认筛选值是会调用此方法
setValue(value) {
this.vm.value = value;
}
// 表格进行筛选时会调用此方法
getValue() {
return this.vm.value;
}
// 表格进行清除筛选时会调用此方法
clean() {
this.vm.value = '';
}
// 表格进行销毁时会调用此方法
destroy() {
if (this.vm) {
const element = this.vm.$el;
this.vm.$destroy();
if (element && element.parentNode) {
element.parentNode.removeChild(element);
}
this.vm = null;
}
}
}
export default class Plugin {
apply() {
return [{
event: "list.render.before",
functional: this.renderBefore.bind(this)
}];
}
renderBefore() {
return Promise.resolve({
filterExtendConfig: {
name: {
components: {
1: FilterComp
}
}
}
});
}
}过滤列表筛选器中单选字段/多选字段类型的选项
export default class Plugin {
apply() {
return [{
event: "list.render.before",
functional: this.renderBefore.bind(this)
}];
}
renderBefore() {
return Promise.resolve({
filterExtendConfig: {
field_0N3ax__c: {
filterOptions(options) { // 此处过滤单选字段/多选字段类型的选项
return options.filter(
(a) => ["91jGaF8hn", "A5137BeV2"].indexOf(a.value) > -1
);
}
}
}
});
}
}设置默认筛选场景并保留部分筛选场景
export default class Plugin {
apply() {
return [{
event: "list.render.before",
functional: this.renderBefore.bind(this)
}];
}
renderBefore() {
return Promise.resolve({
termExtendConfig: {
default: 'All', // 默认展示的场景apiName
retain: ['All', 'InCharge'] // 需保留的场景apiName或ID
}
})
}
}配置列表汇总字段
export default class Plugin {
apply() {
return [{
event: "list.render.before",
functional: this.renderBefore.bind(this)
}];
}
renderBefore() {
return {
// All为筛选场景apiName,请替换为目标列表的真实场景apiName或ID
summaryFields: {
All: [{
type: 'sum',
field_name: 'amount__c'
}]
},
allSummaryFields: {
All: [{
type: 'sum',
field_name: 'amount__c',
api_name: 'sum_amount__c'
}]
}
};
}
}设置图片字段预览尺寸
export default class Plugin {
apply() {
return [{
event: "list.render.before",
functional: this.renderBefore.bind(this)
}];
}
renderBefore() {
return {
// 图片字段扩展配置
imageExtendConfig: {
// key为图片字段apiName
field_0N8Yi__c: {
previewWidth: 500,
previewHeight: 500
}
},
}
}
}扩展列表工具栏按钮执行参数
export default class Plugin {
apply() {
return this.getHooks();
}
getHooks() {
return [{
event: 'list.render.before',
functional: this.listRenderBefore.bind(this)
}];
}
listRenderBefore(context, plugin) {
return {
// 1.如何扩展列表工具栏按钮执行参数
actionExtendConfig: {
// 扩展新建按钮
add: {
parseParam: (data) => ({
// 重写add action参数中的recordTypeFilter属性
recordTypeFilter: ['default__c']
})
}
}
};
}
}自定义列表工具栏按钮
export default class Plugin {
apply() {
return this.getHooks();
}
getHooks() {
return [{
event: 'list.render.before',
functional: this.listRenderBefore.bind(this)
}];
}
listRenderBefore(context, plugin) {
return {
buttons: {
add: [
{
action: "customButton",
label: "自定义对象按钮",
exposed: true, // 外露
placement: { // 放在新建按钮前
base: 'Add',
},
callback({recordType, objectApiName}) {
console.log(recordType, objectApiName);
}
}
],
reset: [{
action: 'Add',
label: "重置按钮名称",
}]
}
};
}
}自定义行操作按钮
export default class Plugin {
apply() {
return [{
event: 'list.render.before',
functional: this.listRenderBefore.bind(this)
}];
}
listRenderBefore() {
return {
operateBtns: [
(rowData) => ({
add: [{
action: 'customRowButton',
label: '查看记录ID',
callback(params) {
console.log(rowData, params.dataId);
}
}]
})
]
};
}
}常见问题
Q: 通过formatListDataAsync修改列表数据,为什么翻页后数据异常?
A: 该函数每次接收当前页的{totalCount, data},必须基于本次入参返回相同结构,不要缓存或复用上一页的data。修改List请求参数请使用formatRequestParam。
