amis Mapping 映射组件完全指南从字典映射到自定义模板渲染【免费下载链接】amis前端低代码框架通过 JSON 配置就能生成各种页面。项目地址: https://gitcode.com/GitHub_Trending/am/amisMapping映射是 amis 低代码框架中用于值 → 展示转换的核心展示型组件它将后端返回的编码值如1、2、happy映射为友好的标签、HTML 甚至任意 amis 组件常用于状态字典、枚举翻译、表格列格式化与表单静态展示。本文以 docs/zh-CN/components/mapping.md 为主体结合 Mapping.tsx 源码与 Mapping.test.tsx 测试用例系统讲解映射配置、HTML/组件/模板渲染、多值展示、远程字典拉取及 Field 场景集成读完后可直接在页面、表格与表单中落地完整的映射方案。基本用法Mapping 组件通过map属性定义编码值 → 展示内容的映射规则通过value或数据域中name关联的变量指定当前要映射的值。最简单的用法如下{ type: page, body: { type: mapping, value: 1, map: { 1: 第一, 2: 第二, 3: 第三, *: 其他 } } }这里value: 1命中map中的1键页面渲染出文本第一。值得注意的是map中的*是一个通配键当 value 未命中任何具体键时会回退到该键对应的值。这一行为在源码 Mapping.tsx 的renderSingleValue中体现——先精确查表找不到再取map[*]。如果 value 为空或未命中且没有配置通配键组件会渲染占位符。从源码的defaultProps可以看到 Mapping.tsx 中默认占位符为-默认 map 为{*: 通配值}。测试用例 Mapping.test.tsx 也验证了无值时渲染text-muted样式的-value1渲染漂亮未命中的value5渲染通配值其他。渲染 HTMLmap的 value 不仅可以是纯文本还可以直接写 HTML 字符串非常适合做带颜色的状态标签{ type: page, body: { type: mapping, value: 2, map: { 1: span classlabel label-info漂亮/span, 2: span classlabel label-success开心/span, 3: span classlabel label-danger惊吓/span, 4: span classlabel label-warning紧张/span, *: span classlabel label-default其他${type}/span } } }上例中value: 2会渲染为绿色success的开心标签。HTML 字符串会被 amis 当作模板渲染因此${type}这类模板语法同样生效通配项中其他${type}会取数据域中的type变量值这一点从 Mapping.tsx 的return render(tpl, label)可以看出——所有非 itemSchema 的映射值最终都通过 tpl 渲染器输出。测试 Mapping.test.tsx 覆盖了该 HTML 场景的快照。渲染其它组件映射值也可以是完整的 amis schema此时 Mapping 会把该 schema 作为子组件渲染出来。例如按状态渲染成不同颜色的 Tag{ type: page, body: { type: mapping, value: 1, map: { 1: { type: tag, label: #4096ff, displayMode: rounded, color: #4096ff }, 2: { type: tpl, tpl: 2 }, *: 其他 } } }这里value: 1会渲染一个圆角蓝色 Tagvalue: 2渲染一个 tpl 文本。源码中的判定逻辑位于 Mapping.tsx当映射值是 object 且包含type字段时判定为 schema通过render(tpl, label)前先给对象补上name字段后按组件渲染当映射值是 object 但没有type字段时则视为纯数据对象默认取label字段展示。注意一旦配置了itemSchema映射值将不再作为 schema 渲染详见下一节。测试 Mapping.test.tsx 验证了 schema 渲染value1时输出与render({type: tag, label: 漂亮})完全一致的 DOM。此外issue #9613 对应的用例 Mapping.test.tsx 展示了在表格列中嵌套status组件做级联映射的用法map[*]的值本身又是一个带map/labelMap的 status schema最终单元格渲染为处理中。渲染自定义模板该能力自2.5.2版本起提供。配置itemSchema可以统一控制所有映射值的渲染模板支持HTML字符串或SchemaNode两种形式。它的渲染入口在 Mapping.tsxrender(mappingItemSchema, itemSchema, {...})渲染时通过createObject(data, isObject(value) ? value : {item: value})把映射值并入数据域——映射值是 object 时其属性可直接用${xxx}取非 object 时通过${item}获取。HTML 或字符串模板当itemSchema是字符串时它作为模板渲染用${item}获取当前映射值{ type: page, body: { type: mapping, value: 1, map: { 1: 第一, 2: 第二, 3: 第三, *: 其他 }, itemSchema: 自定义模板span stylecolor: red${item}/span } }SchemaNode 模板itemSchema也可以是一个 amis schema此时每条映射值都会套用该 schema 渲染例如统一渲染成 Tag{ type: page, body: { type: mapping, value: 1, map: { 1: 第一, 2: 第二, 3: 第三, *: 其他 }, itemSchema: { type: tag, label: ${item} } } }测试 Mapping.test.tsx 验证value1时输出内容与独立渲染tag(漂亮)完全一致。在模板中渲染数据itemSchema模板内的数据来源遵循三条规则映射值是object时用模板语法${xxx}直接取该对象的属性映射值是非object时用${item}获取映射值本身同时还可以访问数据域中的其它变量。示例映射值为对象、itemSchema为 Tag同时引用对象属性与页面数据域变量{ 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} } } }value: 1命中的对象是{label: 开心, color: red}与页面数据{myName: cat}合并后最终渲染出文本cat 开心、红色背景的 Tag。测试 Mapping.test.tsx 展示了普通 map多 key 对象数组配合 itemSchema 时模板可直接引用valueField/labelField命名的字段如${name} ${text}。映射展示多个该能力自1.5.0版本起提供。当value是数组时Mapping 会依次对每个元素做映射并排展示多个结果{ type: page, body: { type: mapping, value: [1, 2, 3, 4, 5], map: { 1: span classlabel label-info漂亮/span, 2: span classlabel label-success开心/span, 3: span classlabel label-danger惊吓/span, 4: span classlabel label-warning紧张/span, *: span classlabel label-default其他/span } } }这里五个状态标签会被依次渲染出来其中4、5均落到通配键其他。其实现位于源码的render()方法 Mapping.tsx当mapKey由getPropValue解析出的值为数组时逐个调用renderSingleValue渲染每个元素外层包裹map-${index}的 key。map 映射源map属性支持两种数据格式k-v 对象和对象数组对象数组自2.5.2起支持。k-v 对象最常见的映射表形式键为待匹配的值值为展示内容{ type: mapping, value: 1, map: { 1: 第一, 2: 第二, 3: 第三, *: 其他 } }对象数组简单对象数组每个元素是单 key对象key 为待匹配值{ type: mapping, value: 1, map: [{1: 第一}, {2: 第二}, {3: 第三}, {*: 其他}] }源码setMap中的归一化逻辑 Mapping.tsx 会识别单 key 对象数组并逐一摊平为 k-v 映射测试 Mapping.test.tsx 验证了该数组格式与 k-v 对象渲染结果一致。多 key 对象数组当数组元素包含多个字段时需要通过valueField指定哪个字段作为匹配value的 key用labelField指定展示字段不配置时默认为label{ 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 } ] } }源码中多 key 对象的处理同样在setMap当对象 keys 数量大于 1 时使用res[now[self.valueField]] now以valueField为键、整个对象为值构建映射。Store 中valueField的默认值为value见 Mapping.tsx。需要注意配置labelField后映射值无法再作为 schema 渲染此时对象统一取labelField字段展示见 Mapping.tsx。另外源码针对 amis-editor 有特殊处理keys 数量为 2 且包含$$id时会先过滤掉$$id再按单 key 对象处理。用作 Field 时当 Mapping 用在 Table 的列Column、List 的内容、Card 卡片内容以及表单的 Static-XXX 中时可以通过name属性关联数据域中的同名变量进行映射。注意type: mapping与type: map等价——注册别名在 Mapping.tsx 的Renderer({type: mapping, alias: [map]})中定义。Table 中的列类型将列type设为mapping并配置name与map即可对每一行数据做字典翻译{ 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 classlabel label-info漂亮/span, 2: span classlabel label-success开心/span, 3: span classlabel label-danger惊吓/span, 4: span classlabel label-warning紧张/span, *: 其他${type} } } ] }List 的内容、Card 卡片的内容配置方式与此相同。另外在 exportExcel.ts 中可以看到表格导出 Excel 时对mapping与static-mapping类型会特殊处理将映射后的展示值写入导出结果。Form 中静态展示在表单中使用static-mapping实现只读字典展示源码兼容层 compat.ts 中mapping: static-mapping表明表单场景下两者可互通{ type: form, data: { type: 2 }, body: [ { type: static-mapping, name: type, label: 映射, map: { 1: span classlabel label-info漂亮/span, 2: span classlabel label-success开心/span, 3: span classlabel label-danger惊吓/span, 4: span classlabel label-warning紧张/span, *: 其他${type} } } ] }name: type使组件从表单数据域读取type变量的值进行映射。布尔值映射映射值可以是布尔类型。提供两种写法写法一用1表示开、0表示关注意此时 value 为true{ type: form, data: { type: true }, body: [ { type: static-mapping, name: type, label: 映射, map: { 1: span classlabel label-info开/span, 0: span classlabel label-default关/span } } ] }写法二直接用true/false作为键{ type: form, data: { type: true }, body: [ { type: static-mapping, name: type, label: 映射, map: { true: span classlabel label-info开/span, false: span classlabel label-default关/span } } ] }两种写法都依赖源码中的布尔兼容逻辑 Mapping.tsx当key true且存在map[1]时命中开当key false且存在map[0]时命中关否则回退到通配键。远程拉取字典该能力自1.1.6版本起提供。字典数据可能来自后端接口。通过配置source属性即可远程拉取接口返回字典对象即可数据格式与map配置一致{ type: form, data: { type: 2 }, body: [ { type: mapping, name: type, label: 映射, source: /api/mapping } ] }从源码看source的加载逻辑在 Mapping.tsx 的reload()方法中normalizeApi将字符串规范化为 API 配置后通过env.fetcher请求Store 的load方法 Mapping.tsx 会从响应中依次识别data.options、data.items、data.records数组否则将整个data作为字典数据。默认 source 有 30s 缓存见 Mapping.tsx 的api.cache api.cache ?? 30 * 1000通常字典数据不长变更如需调整缓存策略参考 API 文档 中缓存相关的配置。当source或接口响应内容变化时组件会在componentDidUpdate中通过isApiOutdated判断并自动重新拉取见 Mapping.tsx。关联上下文变量source也支持配置为变量表达式从当前数据域直接取值作为映射字典注意当数据域里的变量值为$$时表示将所有接口返回的data字段值整体赋值到对应的 key 中。{ type: form, initApi: { url: /api/mapping, method: get, responseData: { zidian: $$$$, type: 2 } }, body: [ { type: mapping, name: type, label: 映射, source: $${zidian} } ] }initApi通过responseData将接口返回的data整体赋给变量zidianMapping 的source: $${zidian}则引用该变量。源码中变量型 source 的处理在 Mapping.tsxisPureVariable(source)判定后调用resolveVariableAndFilter(source, data, | raw)解析变量并store.setMap(...)直接设为映射表componentDidUpdate中还会对比变量前后值变化时自动更新映射见 Mapping.tsx。占位文本当数据不存在时可通过placeholder控制展示内容{ type: page, body: { type: mapping, placeholder: 数据不存在, map: { 1: 第一, 2: 第二, 3: 第三, *: 其他 } } }例如value为空字符串、null或 undefined 时组件会渲染placeholder指定的文本。源码实现中占位文本渲染在 Mapping.tsx默认值为-见 defaultProps并以text-muted样式输出测试用例对此有专门断言Mapping.test.tsx。属性表属性名类型默认值说明classNamestring外层 CSS 类名placeholderstring-占位文本源码 defaultProps 默认值为-mapobject或Arrayobject映射配置支持 k-v 对象、简单对象数组、多 key 对象数组sourcestringorAPI远程数据源或变量表达式详见 API 文档 与 数据映射默认 30s 缓存valueFieldstringvalue2.5.2起map 或 source 为Arrayobject时用来匹配映射的字段名Store 中默认值为value见 Mapping.tsxlabelFieldstringlabel2.5.2起map 或 source 为Arrayobject时用来展示的字段名注配置后映射值无法作为 schema 组件渲染itemSchemastring或SchemaNode2.5.2自定义渲染模板支持html或SchemaNode当映射值是非object时可使用${item}获取映射值当映射值是object时可使用映射语法${xxx}获取object的值也可使用数据映射语法${xxx}获取数据域中变量值小结Mapping 组件以极简的 JSON 配置覆盖了从基础字典翻译到复杂自定义渲染的完整链路map支持 k-v 对象与对象数组valueField/labelField映射值可以是文本、HTML、任意 amis schemaitemSchema提供统一的模板化渲染数组 value 支持多值并列展示source支持远程字典拉取默认 30s 缓存与上下文变量引用在 Table 列、List、Card 与表单static-mapping中通过name即可无缝复用。结合 Mapping.tsx 源码与 Mapping.test.tsx 测试开发者可以精确掌握其匹配优先级精确键 → 布尔兼容键 → 通配键、对象归一化规则与数据域合并机制在实际项目中灵活构造可维护的枚举展示方案。【免费下载链接】amis前端低代码框架通过 JSON 配置就能生成各种页面。项目地址: https://gitcode.com/GitHub_Trending/am/amis创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考