npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

antd-form-linkage

v2.0.2

Published

Antd form linkage components

Downloads

52

Readme

Antd Form Linkage


✨ 特性

  • 🎯 声明式配置 - 使用依赖图描述字段间的联动关系,告别繁琐的命令式代码
  • 级联联动 - 自动拓扑排序,支持 A → B → C 多级联动链
  • 🔄 异步支持 - 原生支持 async/await,轻松处理远程数据加载
  • 🎨 丰富效果 - 支持值重置、禁用、隐藏、选项禁用、必填状态等多种联动效果
  • 🐛 调试工具 - 内置可视化调试面板,实时查看联动状态
  • 📦 TypeScript - 完整的类型定义,提供良好的开发体验
  • 🔌 易于集成 - 与 Ant Design Form 无缝配合,零学习成本

📦 安装

npm install antd-form-linkage

# 或使用 yarn
yarn add antd-form-linkage

# 或使用 pnpm
pnpm add antd-form-linkage

前置依赖

{
  "peerDependencies": {
    "antd": ">=4.20.1",
    "react": ">=16.8.0",
    "react-dom": ">=16.8.0",
    "lodash": ">=4.17.0"
  }
}

🚀 快速开始

基础用法

import { LinkageForm, LinkageFormItem, LinkageConfig } from 'antd-form-linkage';
import { Select, Input } from 'antd';

// 1. 定义联动配置
const linkageConfig: LinkageConfig = {
  debug: true, // 开启调试模式
  fields: [
    {
      name: 'targetField',           // 受控字段名
      dependencies: ['triggerField'], // 依赖的字段
      compute: ({ triggerField }) => {
        // 根据触发字段的值,返回受控字段的状态
        if (triggerField === 'disable') {
          return { disabled: true };
        }
        if (triggerField === 'hide') {
          return { hidden: true };
        }
        return { disabled: false, hidden: false };
      },
    },
  ],
};

// 2. 使用组件
function MyForm() {
  return (
    <LinkageForm linkage={linkageConfig}>
      <LinkageFormItem name="triggerField" label="触发字段">
        <Select
          options={[
            { value: 'normal', label: '正常' },
            { value: 'disable', label: '禁用目标' },
            { value: 'hide', label: '隐藏目标' },
          ]}
        />
      </LinkageFormItem>

      <LinkageFormItem name="targetField" label="目标字段">
        <Input placeholder="这个字段会根据触发字段变化" />
      </LinkageFormItem>
    </LinkageForm>
  );
}

级联选择(省市区三级联动)

const linkageConfig: LinkageConfig = {
  fields: [
    {
      name: 'city',
      dependencies: ['province'],
      compute: ({ province }) => ({
        value: undefined, // 省份变化时清空城市
        options: getCityOptions(province), // 根据省份获取城市列表
      }),
    },
    {
      name: 'district',
      dependencies: ['city'],
      compute: ({ city }) => ({
        value: undefined, // 城市变化时清空区县
        options: getDistrictOptions(city), // 根据城市获取区县列表
      }),
    },
  ],
};

计算字段

const linkageConfig: LinkageConfig = {
  fields: [
    // 自动计算总价
    {
      name: 'total',
      dependencies: ['price', 'quantity'],
      compute: ({ price, quantity }) => ({
        value: (price || 0) * (quantity || 0),
      }),
    },
    // 总价超过 1000 时显示折扣字段
    {
      name: 'discount',
      dependencies: ['total'],
      compute: ({ total }) => ({
        hidden: total < 1000,
      }),
    },
  ],
};

异步联动

const linkageConfig: LinkageConfig = {
  fields: [
    {
      name: 'userInfo',
      dependencies: ['userId'],
      compute: async ({ userId }) => {
        if (!userId) return { value: null };
        
        // 异步获取用户信息
        const response = await fetch(`/api/users/${userId}`);
        const data = await response.json();
        
        return { value: data };
      },
    },
  ],
};

📖 API 文档

LinkageForm 组件

包装了 Ant Design Form,提供联动能力。

<LinkageForm
  linkage={linkageConfig}  // 联动配置
  form={form}              // 可选,Form 实例
  onValuesChange={...}     // 值变化回调
  {...otherFormProps}      // 其他 antd Form 属性
>
  {children}
</LinkageForm>

| 属性 | 类型 | 必填 | 描述 | |------|------|------|------| | linkage | LinkageConfig | 否 | 联动配置 | | form | FormInstance | 否 | Form 实例,不传则内部创建 | | ...props | FormProps | - | 其他 Ant Design Form 属性 |

LinkageFormItem 组件

包装了 Ant Design Form.Item,自动应用联动状态。

<LinkageFormItem
  name="fieldName"    // 字段名
  type="Select"       // 可选,表单项类型
  label="字段标签"
  {...otherFormItemProps}
>
  <Select options={...} />
</LinkageFormItem>

| 属性 | 类型 | 必填 | 描述 | |------|------|------|------| | name | string | 是 | 字段名 | | type | FormItemType | 否 | 表单项类型,用于智能处理 options | | ...props | FormItemProps | - | 其他 Ant Design Form.Item 属性 |

支持的 type 值:

  • Input / Select / DatePicker / Cascader / TreeSelect
  • Radio / Checkbox / UploadButton
  • CheckAllCheckBox / MultiCategory / RadioCheckBoxComb

LinkageDevTools 调试面板

可视化调试面板,帮助开发调试联动逻辑。

<LinkageForm linkage={config}>
  {/* 表单项 */}
  <LinkageDevTools defaultOpen position="bottom-right" />
</LinkageForm>

| 属性 | 类型 | 默认值 | 描述 | |------|------|--------|------| | defaultOpen | boolean | false | 是否默认展开 | | position | string | 'bottom-right' | 位置:bottom-right / bottom-left / top-right / top-left | | hideInProduction | boolean | true | 是否在生产环境隐藏 |

LinkageConfig 配置类型

interface LinkageConfig {
  /** 字段节点列表 */
  fields: FieldNode[];
  
  /** 是否在表单初始化时计算所有字段 */
  computeOnMount?: boolean;
  
  /** 调试模式(在控制台输出日志) */
  debug?: boolean;
}

FieldNode 字段节点

interface FieldNode {
  /** 字段名称(对应 Form.Item 的 name) */
  name: string;
  
  /** 依赖的字段列表 */
  dependencies?: string[];
  
  /**
   * 计算函数 - 当依赖字段变化时触发
   * @param deps 依赖字段的当前值
   * @param form antd Form 实例
   * @param allValues 所有表单值
   * @returns 计算结果(支持 Promise)
   */
  compute?: (
    deps: Record<string, any>,
    form: FormInstance,
    allValues: Record<string, any>
  ) => FieldComputeResult | Promise<FieldComputeResult>;
  
  /** 是否在初始化时执行 compute */
  computeOnMount?: boolean;
  
  /** 防抖延迟(毫秒) */
  debounce?: number;
}

FieldComputeResult 计算结果

interface FieldComputeResult {
  /** 设置字段值 */
  value?: any;
  
  /** 禁用状态 */
  disabled?: boolean;
  
  /** 隐藏状态 */
  hidden?: boolean;
  
  /** 隐藏但仍收集值 */
  hiddenAndSave?: boolean;
  
  /** 选项列表(用于 Select/Radio/Checkbox 等) */
  options?: OptionConfig[];
  
  /** 必填状态 */
  required?: boolean;
}

🛠️ 辅助函数

提供便捷的字段创建函数,简化常见场景:

import { createField } from 'antd-form-linkage';

const config: LinkageConfig = {
  fields: [
    // 1. 条件显隐 - 总价 >= 1000 时显示折扣字段
    createField.conditionalVisible(
      'discount',              // 字段名
      ['total'],               // 依赖字段
      ({ total }) => total >= 1000  // 显示条件
    ),
    
    // 2. 条件禁用 - 未勾选同意时禁用提交按钮
    createField.conditionalDisabled(
      'submit',
      ['agree'],
      ({ agree }) => !agree
    ),
    
    // 3. 计算字段 - 自动计算总价
    createField.computed(
      'total',
      ['price', 'quantity'],
      ({ price, quantity }) => price * quantity
    ),
    
    // 4. 级联重置 - 省份变化时清空城市
    createField.cascadeReset('city', 'province', undefined),
  ],
};

🔧 Hooks API

useLinkageEngine

创建联动引擎实例,用于自定义场景:

import { useLinkageEngine } from 'antd-form-linkage';

function MyComponent() {
  const [form] = Form.useForm();
  const engine = useLinkageEngine(form, linkageConfig);
  
  // 手动触发重新计算
  const handleRefresh = () => {
    engine?.recompute();
  };
  
  // 获取字段状态
  const fieldState = engine?.getFieldState('myField');
  
  return <Form form={form}>...</Form>;
}

useFieldState

订阅单个字段的联动状态:

import { useFieldState } from 'antd-form-linkage';

function FieldStatus({ name }: { name: string }) {
  const fieldState = useFieldState(name);
  
  return (
    <div>
      <p>字段: {name}</p>
      <p>禁用: {fieldState?.disabled ? '是' : '否'}</p>
      <p>隐藏: {fieldState?.hidden ? '是' : '否'}</p>
      <p>加载中: {fieldState?.loading ? '是' : '否'}</p>
    </div>
  );
}

useAllFieldStates

订阅所有字段的联动状态:

import { useAllFieldStates } from 'antd-form-linkage';

function AllFieldsStatus() {
  const allStates = useAllFieldStates();
  
  return (
    <ul>
      {Array.from(allStates.entries()).map(([name, state]) => (
        <li key={name}>{name}: {JSON.stringify(state)}</li>
      ))}
    </ul>
  );
}

🐛 调试指南

方式一:使用调试面板

import { LinkageDevTools } from 'antd-form-linkage';

<LinkageForm linkage={{ ...config, debug: true }}>
  {/* 表单项 */}
  <LinkageDevTools defaultOpen />
</LinkageForm>

调试面板功能:

  • 📊 实时显示所有字段的联动状态
  • 🔍 展开查看详细信息(value、options 等)
  • 🎯 状态标签快速识别(禁用、隐藏、加载中)
  • 🐛 错误信息展示

方式二:控制台日志

开启 debug: true 后,会在控制台输出详细日志:

[Linkage] 值变化: ['province'] { province: 'zhejiang' }
[Linkage] 受影响的字段: ['city', 'district']
[Linkage] 计算顺序: ['city', 'district']
[Linkage] 计算字段: city { province: 'zhejiang' }
[Linkage] 字段状态更新: city { value: undefined, options: [...] }
[Linkage] 批量更新值: { city: undefined }

🔄 从旧版迁移

如果你之前使用的是旧版静态配置格式,可以使用 convertLegacyConfig 一键转换:

import { convertLegacyConfig } from 'antd-form-linkage';

// 旧版配置格式
const oldConfig = {
  activeItem1: {
    2: [
      { formName: 'targetItem1', changeValue: 1, disabled: true },
      { formName: 'targetItem2', changeValue: undefined, hidden: true },
    ],
  },
};

// 转换为新版配置
const newConfig = convertLegacyConfig(oldConfig);

// 使用新配置
<LinkageForm linkage={newConfig}>...</LinkageForm>

📝 完整示例

项目包含了丰富的示例,运行查看:

cd form-linkage-config
npm install
npm run dev

示例包括:

  • 🎯 基础联动 - 禁用、隐藏、自动填值、选项禁用
  • 🏙️ 级联选择 - 省市区三级联动
  • 🧮 计算字段 - 价格计算、条件显示
  • 🔗 多依赖联动 - 一个字段依赖多个字段
  • 表单验证联动 - 条件必填、密码确认

🏗️ 架构设计

┌─────────────────────────────────────────────────────────┐
│                    LinkageForm                          │
│  ┌─────────────────────────────────────────────────────│
│  │                LinkageProvider                       │
│  │  ┌───────────────────────────────────────────────── │
│  │  │              LinkageEngine                       │
│  │  │  ┌─────────────────────────────────────────────  │
│  │  │  │  依赖图 (Dependency Graph)                    │
│  │  │  │  ┌─────┐    ┌─────┐    ┌─────┐               │
│  │  │  │  │  A  │───▶│  B  │───▶│  C  │               │
│  │  │  │  └─────┘    └─────┘    └─────┘               │
│  │  │  │       拓扑排序 → 按序计算 → 批量更新          │
│  │  │  └─────────────────────────────────────────────  │
│  │  └───────────────────────────────────────────────── │
│  │                                                      │
│  │  ┌────────────────┐  ┌────────────────┐             │
│  │  │LinkageFormItem │  │LinkageFormItem │  ...        │
│  │  │  useFieldState │  │  useFieldState │             │
│  │  └────────────────┘  └────────────────┘             │
│  └─────────────────────────────────────────────────────│
└─────────────────────────────────────────────────────────┘

核心流程:

  1. 值变化 → 触发 onValuesChange
  2. 查找依赖 → BFS 遍历依赖图,找出所有受影响字段
  3. 拓扑排序 → 确保依赖的字段先计算
  4. 按序计算 → 执行 compute 函数,支持异步
  5. 批量更新 → 合并所有更新,一次性应用

📄 License

MIT © [Your Name]