Skip to content

加载外部数据

在 FormCreate 中,loadData 属性允许从本地或外部数据源加载数据,并将其插入到表单组件的特定位置。此功能在处理动态表单数据时非常有用。

类型

ts
interface LoadDataEffectOption {
    // 数据名
    attr: String;
    // 插入位置, 默认 `options`
    to?: String;
    // 加载时是否深拷贝, 默认为 `false`
    copy?: boolean;
    // 数据源变化时, 是否同步修改, 默认为 `true`
    watch?: boolean;
}
type LoadData = LoadDataEffectOption | LoadDataEffectOption[];

注意事项

  • loadData 支持将数据插入到表单组件的任意位置,通常是 options 或 props.options。
  • 通过设置 copy 属性,可以在加载时深拷贝数据,以防止数据引用带来的副作用。
  • 当 watch 为 true 时,数据源发生变化会自动更新表单组件的数据。

使用方法

  1. 通过 formCreate.setData 方法写入数据

在使用 loadData 之前,可以通过 formCreate.setData 方法预加载数据:

js
formCreate.setData('labelOptions', [
    {label: '很好用', value: 0},
    {label: '很快速', value: 1},
    {label: '很高效', value: 2},
    {label: '很全能', value: 3},
  ])
  1. 在 loadData 中配置对应的数据名

在表单规则中,使用 loadData 配置项来加载数据:

js
{
    effect: {
        loadData: {
            // 数据名
            attr: 'labelOptions',
            // 插入位置
            to: 'options'
        }
    }
}

API 介绍

setData

挂载自定义数据,使其在表单中可用,方便在组件间共享数据。

  • 类型
ts
type SetData = (name:string,value:any) => void;
  • 示例
js
 formCreate.setData('options',[
        {label:'好用',value:0},
        {label:'快速',value:1},
        {label:'高效',value:2},
        {label:'全能',value:3},
 ]);

setDataDriver

导入自定义的数据获取函数,允许你根据特定的逻辑从外部数据源中获取数据。

  • 类型
ts
type SetDataDriver = (id: string, callback: (key: string) => any) => void;
  • 示例
js
formCreate.setDataDriver('$user', function(key) {
    return $store.state.user[key];
});

setDataDriver 方法允许你为表单指定数据驱动函数,使得表单组件可以动态地获取数据。例如,你可以从 Vuex 状态管理中获取用户数据,并在表单中显示。

getData

获取先前通过 setData 挂载的自定义数据。

  • 类型
ts
type GetData = (name: string) => any;
  • 示例
js
const options = formCreate.getData('options');
console.log(options);

removeData

移除之前通过 setData 方法挂载的自定义数据。

  • 类型
ts
type RemoveData = (name:string) => void;
  • 示例
js
formCreate.removeData('options');

refreshData

手动刷新与特定数据相关的表单渲染,确保表单组件的显示和数据保持同步。

  • 类型
ts
type RefreshData = (name:string) => void;
  • 示例
js
formCreate.refreshData('options');

示例

根据用户角色动态加载表单选项

在实际业务中,可能需要根据用户的角色来动态显示不同的表单选项。通过 loadData 配合 setDatasetDataDriver,我们可以轻松实现这一点。

js
// 假设用户角色存储在 Vuex 中
formCreate.setDataDriver('$roleOptions', function(key) {
    const role = $store.state.user.role;
    if (role === 'admin') {
        return [
            { label: '管理员选项1', value: 'admin_option_1' },
            { label: '管理员选项2', value: 'admin_option_2' }
        ];
    } else {
        return [
            { label: '用户选项1', value: 'user_option_1' },
            { label: '用户选项2', value: 'user_option_2' }
        ];
    }
});


const rules = [
    {
        type: 'select',
        field: 'role_based_options',
        title: '根据角色选择',
        effect: {
            loadData: {
                attr: '$roleOptions',
                to: 'options'
            }
        }
    }
];

依赖于外部数据源的实时更新表单

在复杂的企业应用中,表单可能需要实时依赖于外部数据源(如库存系统)进行数据更新。使用 refreshData,可以确保表单中的数据始终保持最新状态。

js
// 定期从外部系统刷新库存数据
setInterval(() => {
    fetch('/api/inventory')
        .then(res => res.json())
        .then(data => {
            formCreate.setData('inventoryOptions', data);
            formCreate.refreshData('inventoryOptions');
        });
}, 60000);  // 每分钟刷新一次


const rules = [
    {
        type: 'select',
        field: 'product',
        title: '选择产品',
        effect: {
            loadData: {
                attr: 'inventoryOptions',
                to: 'options'
            }
        }
    }
];

基于其他字段的选择动态加载数据

在复杂表单中,用户选择一个字段的值后,可能需要动态加载与该选择相关的数据。通过 loadData 配合 onChange 事件,可以实现这样的逻辑。

js
// 初始化类别数据
formCreate.setData('categoryOptions', {
    electronics: [
        { label: '手机', value: 'phone' },
        { label: '电脑', value: 'computer' }
    ],
    clothing: [
        { label: 'T恤', value: 'tshirt' },
        { label: '牛仔裤', value: 'jeans' }
    ]
});


const rules = [
    {
        type: 'select',
        field: 'category',
        title: '选择类别',
        options: [
            { label: '电子产品', value: 'electronics' },
            { label: '服装', value: 'clothing' }
        ],
        inject: true,
        on: {
            change(inject, val) {
                const products = inject.api.getData('categoryOptions')[val] || [];
                inject.api.getRule('products').options = products;
            }
        }
    },
    {
        type: 'select',
        field: 'products',
        title: '选择产品',
        options: []
    }
];

复杂依赖关系的动态表单

这个示例展示了如何根据用户选择的国家和城市来动态加载区域信息。

js
formCreate.setData('regionOptions', {
    'us-ny': [
        { label: '曼哈顿', value: 'manhattan' },
        { label: '布鲁克林', value: 'brooklyn' }
    ],
    'us-ca': [
        { label: '洛杉矶', value: 'los_angeles' },
        { label: '旧金山', value: 'san_francisco' }
    ],
    'cn-bj': [
        { label: '朝阳区', value: 'chaoyang' },
        { label: '海淀区', value: 'haidian' }
    ],
    'cn-sh': [
        { label: '浦东新区', value: 'pudong' },
        { label: '徐汇区', value: 'xuhui' }
    ]
});


const rules = [
    {
        type: 'select',
        field: 'country',
        title: '选择国家',
        options: [
            { label: '美国', value: 'us' },
            { label: '中国', value: 'cn' }
        ],
        inject: true,
        on: {
            change(inject) {
                inject.api.setValue('city', ''); // 清空城市选择
                inject.api.setValue('region', ''); // 清空区域选择
            }
        }
    },
    {
        type: 'select',
        field: 'city',
        title: '选择城市',
        options: [
            { label: '纽约', value: 'ny', belong: 'us' },
            { label: '加州', value: 'ca', belong: 'us' },
            { label: '北京', value: 'bj', belong: 'cn' },
            { label: '上海', value: 'sh', belong: 'cn' }
        ],
        inject: true,
        on: {
            change(inject, val) {
                const country = inject.api.getValue('country');
                if (country && val) {
                    const key = `${country}-${val}`;
                    const options = inject.api.getData('regionOptions')[key] || [];
                    inject.api.getRule('region').options = options;
                    inject.api.setValue('region', ''); // 清空区域选择
                }
            }
        }
    },
    {
        type: 'select',
        field: 'region',
        title: '选择区域',
        options: []
    }
];

说明

  1. 使用 formCreate.setData 提前设置 regionOptions,以便在不同的国家和城市组合下加载对应的区域选项。
  2. 当用户选择国家时,会清空城市和区域选择。
  3. 当用户选择城市时,触发 onChange 事件,根据所选国家和城市动态加载对应的区域。
  4. 根据用户选择的国家和城市组合,动态更新区域选项

远程加载数据

如果您希望从远程 API 动态加载区域数据,而不是在前端静态定义,可以使用以下方式:

js
formCreate.setDataDriver('regionOptions', function(key) {
    return axios.get(`/api/regions/${key}`).then(res => res.data);
});


const fApi = formCreate.create([
    {
        type: 'select',
        field: 'country',
        title: '选择国家',
        options: [
            { label: '美国', value: 'us' },
            { label: '中国', value: 'cn' }
        ],
        inject: true,
        on: {
            change(inject) {
                inject.api.setValue('city', ''); // 清空城市选择
                inject.api.setValue('region', ''); // 清空区域选择
            }
        }
    },
    {
        type: 'select',
        field: 'city',
        title: '选择城市',
        options: [
            { label: '纽约', value: 'ny', belong: 'us' },
            { label: '加州', value: 'ca', belong: 'us' },
            { label: '北京', value: 'bj', belong: 'cn' },
            { label: '上海', value: 'sh', belong: 'cn' }
        ],
        on: {
            change(inject, val) {
                const country = inject.api.getValue('country');
                if (country && val) {
                    const key = `${country}-${val}`;
                    inject.api.getRule('region').props.loading = true;
                    inject.api.getData('regionOptions', key).then(options => {
                        inject.api.updateRule('region', {
                            props: {
                                options, loading: false
                            }
                        }).props.loading = false;
                        inject.api.setValue('region', ''); // 清空区域选择
                    });
                }
            }  
        }
    },
    {
        type: 'select',
        field: 'region',
        title: '选择区域',
        options: []
    }
]);

说明

  1. 定义了一个数据驱动器,可以根据提供的 key 动态从 API 获取数据。
  2. 当国家和城市选择发生变化时,调用数据驱动器从远程 API 获取区域选项,并更新表单组件的选项。

以上展示了 FormCreate 在处理复杂动态表单场景中的强大功能。通过灵活使用 loadData、setData、onChange 等方法,您可以实现各种复杂的业务逻辑,使表单更加智能和动态化。无论是实时校验、依赖关系处理,还是动态数据加载,FormCreate 都能提供强大的支持。

FormCreate 是一个开源项目,基于 MIT 许可证发布,欢迎个人和企业用户免费使用