Skip to content

修改内置组件功能

在二开场景中,你经常会遇到“内置组件差一点就满足需求”的情况:需要加一个交互、补一个事件、改一下回显逻辑、或者兼容历史数据格式。本文介绍在设计器中,如何对“内置组件”进行功能改造,并给出两种内置组件的推荐处理方式。

你要改哪些地方?

“修改内置组件功能”通常涉及 3 层(按需选择):

  • 组件实现(Runtime Component):真正决定交互、v-model、事件与展示的 Vue 组件
  • 规则/配置(DragRule,可选):如果你新增/修改了可配置项,需要同步更新对应的规则定义与多语言
  • 注册与覆盖(仅渲染器内置组件):不改渲染器源码,通过“同名组件覆盖”的方式替换内置实现

下面分两类说明。

一、修改设计器内置组件

设计器内置组件属于设计器项目自身的一部分,通常可以直接在组件文件内完成改造,成本最低、定位最直观。

参考位置(以 SignaturePad 为例)

  • PC 组件/src/components/SignaturePad.vue
  • Mobile 组件/src/components/mobile/SignaturePad.vue

实施步骤

1. 备份默认代码

建议用“最轻量、可长期维护”的备份方式之一:

  • 方式 A:同目录备份文件(最快)
    • 例如:SignaturePad.vue.bakSignaturePad.vue.default
    • 同时建议把 *.bak / *.default 加入项目的 .gitignore(避免误提交)
  • 方式 B:用 Git 保存一份“原版快照”(最推荐)
    • 建议在修改前保留一次提交或打 tag,后续升级/回滚最省事

WARNING

“备份”不是为了多一份文件,而是为了在升级设计器版本、对比差异、回滚问题时,有一个可追溯的基线。

2. 直接修改组件实现 (SignaturePad.vue)

常见改造点(按需选择):

  • 交互逻辑:比如新增按钮、增加快捷操作、修复边界输入
  • 数据格式:调整输出值格式(保持向后兼容,见下文“兼容建议”)
  • 事件抛出:补齐 change、自定义事件(例如 clearconfirm
  • 只读/阅读模式:根据 disabledformCreateInject.preview 提供更合理的回显
  • 跨端一致性:如果同时支持 PC/Mobile,建议两端保持同名同契约

3. 如有新增配置项,同步更新 DragRule

如果你的功能改造引入了新的 props.xxx、新增了右侧面板配置项,需要同步改 DragRule:

  • 对应规则文件一般在 /src/config/rule/*
  • 同步补齐多语言(如 /src/locale/*

否则会出现“组件支持了新能力,但设计器右侧无法配置”的割裂体验。

二、修改渲染器内置组件

渲染器内置组件存在于渲染器包(例如 Element Plus / Ant Design Vue / Vant 的渲染器实现)中,不推荐直接修改渲染器源码

  • 升级成本高:一升级就容易丢改动/产生冲突
  • 影响面大:改动会对所有使用方产生全局影响,排查困难

因此更推荐使用“开发一个同名组件并挂载”的方式覆盖内置组件。

原理:同名注册会覆盖内置实现

form-create 允许通过 formCreate.component(key, Comp) 注册组件;当 key 与内置组件同名时,后注册的组件会覆盖内置组件。

更通用的说明可参考文档:覆盖内置组件

实施步骤

1. 确认你要覆盖的组件 key(必须一致)

你需要知道该内置组件在规则里使用的 type(也就是注册 key),例如:inputselectradio 等。

2. 开发一个“同名组件”

开发一个自定义组件,并尽量保持与原组件功能兼容(非常关键):

  • v-modelmodelValue + update:modelValue(Vue2 则为 value + input
  • disabled:支持禁用
  • change:建议透出 change(便于统一监听)
  • attrs 透传v-bind="$attrs",避免丢失渲染器/规则传入的原生属性
  • 插槽/事件兼容(按需):尽量保持常用 slot、事件名不变

3. 在应用启动阶段完成覆盖注册(越早越好)

在创建任何表单实例之前执行覆盖注册,例如:

js
import formCreate from '@form-create/element-ui';
import CustomInput from './CustomInput.vue';

// 覆盖内置 input
formCreate.component('input', CustomInput);

常见问题排查

1. 覆盖渲染器内置组件后,部分表单配置失效

  • 最可能原因:自定义组件没有 v-bind="$attrs",导致规则传入的 props/事件丢失
  • 修复建议:补齐 attrs 透传,并检查 emits 是否包含必要事件

2. 历史表单出现异常(值类型不兼容/回显错误)

  • 最可能原因:你修改了输出值格式,但没有兼容旧格式
  • 修复建议:在组件内部对旧值做兼容解析,或提供“迁移脚本/转换函数”

兼容性建议

  • 尽量不改 rule.type:改 type 会直接影响历史规则渲染
  • 新增能力优先“向后兼容”:旧配置仍能正常工作,新配置只是增强
  • 覆盖渲染器组件时尽量保持 API 不变:属性名、事件名、插槽尽量沿用原组件
  • 跨端同名同契约:PC/Mobile 最好保持一致,避免同一份规则跨端表现不一致