MST Form Type V2 —— 动态表单

在V1版本解决在MST中搭建静态表单之后,V2版本重写了整体架构,改变了Schema的格式,新支持了一层深度的动态表单,并且优化了校验和初始化逻辑,支持更多场景。

链接

www.npmjs.com/package/mst...

安装

npm i mst-form-type -S

注意:需要自行安装mobx-state-tree的5.0.0以上版本。

使用

typescript 复制代码
import createForm from 'mst-form-type'

const dynamicForm: FormSchema = {
  static: [
    {
      id: 'name',
      default: '',
      validator: 'required',
    },
    {
      id: 'des',
      default: '',
    },
  ],
  dynamic: [
    {
      id: 'price', // group id
      limit: 100,
      schema: [
        {
          id: 'itemName',
          default: '',
          validator: 'required',
        },
        {
          id: 'itemPrice',
          default: 10,
        },
      ],
      default: [
        {
          itemName: 'itemName1',
          itemPrice: 5,
        },
        {
          itemName: 'itemName2',
          itemPrice: 20,
        },
      ],
      onAdd: i => {
        console.log('add', i)
      },
      onRemove: i => {
        console.log('remove', i)
      },
      onEdit: key => {
        console.log('edit', key)
      },
    },
  ],
}

// render dynamic fields
model.dynamicForm['price'].fields.map(fields => ({ ... }))

// field action
model.dynamicForm.onAdd('price') // this will use field default value in schema
model.dynamicForm.onRemove('price', fields.id)

// form action
model.dynamicForm.submit()
model.dynamicForm.reset()
model.dynamicForm.clear('price') // this will clear all dynamic fields, including default ones

const Main = types.model('Main', {
  form: createForm(schema, 'name?')
  ...
})

// change field value
model.form.setValue({ key, value })
// change dynamic field value
model.form.setDynamicValue({ groupId, id, key, value })
// submit form
model.form.submit() => { key1: value1, key2: value2, ... }

APIs

mst-form-type通过default export提供了一个函数接受schema,生成新的type,将该form相关的伴随状态都包裹在了新type之内。

V2改变了Schema的格式,新的Schema直接区分了静态field和动态field,并统一了field的Schema,让Schema的定义更加清晰。针对动态field的需要,使用新的key定义增加的功能。

schema

typescript 复制代码
// Old
type schema = {
  [key: string]: {
    default: string | number
    validator?: 'required' | ((...args: any[]) => boolean) | RegExp | undefined | null
  }
}

// New
export type TValidator = 'required' | ((...args: any[]) => boolean) | RegExp | undefined | null

export type TValue = string | boolean | number | Record<string, string> | Array<any>

interface FieldSchema {
  id: string
  type?: 'string' | 'number' | 'object' | 'array' | 'boolean'
  default: TValue
  validator?: TValidator
  msg?: string
}

interface DynamicFields {
  id: string
  limit: number
  schema: FieldSchema | FieldSchema[]
  default: Array<Record<string, TValue>>
  onAdd?: (arg) => any
  onRemove?: (id: string) => any
  onEdit?: (key: string) => void
}

interface FormSchema {
  static: FieldSchema[]
  dynamic?: DynamicFields[]
}

在不需要动态field的情况下,V1的Schema格式继续支持,但是底层的逻辑是在没有'dynamic'这个 key的情况下,把所有的key都放到'static'的key中,并用原本的key作为field id。所以,如果不是遗留代码,推荐直接使用新的Schema。

注意,虽然value支持多种类型,但由于传给API时都会转化成字符串,建议直接在value中使用字符串

props

form type上的props没有增加,只是把'internalStatus'改为了'_internalStatus'。

在底层新增了field type。在V2中,每个field type的instance会持有自己的状态,例如value,validator,status等。这些状态不再存在于form type的instance中。如果需要,可以获取到field实例,使用field上面的props。

动态field还增加了一层group type,在group type中包含多组动态field。渲染时需要通过groupId.fields按数组进行渲染,数组元素为一组field实例。同时group type中会承载这组动态field的相关属性和回调方法。还可以通过group的size prop和limit prop,获取当前动态field的数量和最多限制。

actions

除了V1的action,V2主要增加了针对动态field的action,并且移除了initVal这个action,下面分别介绍:

注意,一些action是在group type上的,在form type上会调用失败

getValues()

存在于group type,获取当前所有动态field的值,以数组形式返回。

setDynamicValue({ groupId, id, key, value })

存在于form type,设定单一特定动态field的值,本质上通过groupId找到对应的group instance后,调用其上的editFields实现。

onAdd(groupId, item)

存在于form type,为指定的group增加一组新的动态field,内容为item参数,如果不传,则使用schema中field设定的默认值。本质上通过groupId找到对应的group instance后,调用其上的addFields实现。

onRemove(groupId, itemId)

存在于form type,删除指定的group中的id为itemId的动态field。本质上通过groupId找到对应的group instance后,调用其上的removeFields实现。

onEdit(groupId, itemId, key, value)

存在于form type,修改指定的group中的id为itemId的动态field的value,和setDynamicValue的作用完全一样。本质上通过groupId找到对应的group instance后,调用其上的editFields实现。

clear()

存在于form type,清除所有的动态field,不光是值,只清除值用reset()。

Issue

github.com/sherlockwan...

相关推荐
uhakadotcom19 分钟前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom23 分钟前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom24 分钟前
React与Next.js:基础知识及应用场景
前端·面试·github
uhakadotcom33 分钟前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试
uhakadotcom43 分钟前
Node.js 包管理器:npm vs pnpm
前端·javascript·面试
LaoZhangAI2 小时前
2025最全GPT-4o图像生成API指南:官方接口配置+15个实用提示词【保姆级教程】
前端
ONE_Gua2 小时前
chromium魔改——CDP(Chrome DevTools Protocol)检测01
前端·后端·爬虫
LaoZhangAI2 小时前
2025最全Cherry Studio使用MCP指南:8种强大工具配置方法与实战案例
前端
咖啡教室2 小时前
前端开发日常工作每日记录笔记(2019至2024合集)
前端·javascript
溪饱鱼2 小时前
Nuxt3能上生产吗?
前端