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...

相关推荐
万叶学编程3 小时前
Day02-JavaScript-Vue
前端·javascript·vue.js
前端李易安4 小时前
Web常见的攻击方式及防御方法
前端
PythonFun5 小时前
Python技巧:如何避免数据输入类型错误
前端·python
知否技术5 小时前
为什么nodejs成为后端开发者的新宠?
前端·后端·node.js
hakesashou5 小时前
python交互式命令时如何清除
java·前端·python
天涯学馆5 小时前
Next.js与NextAuth:身份验证实践
前端·javascript·next.js
HEX9CF5 小时前
【CTF Web】Pikachu xss之href输出 Writeup(GET请求+反射型XSS+javascript:伪协议绕过)
开发语言·前端·javascript·安全·网络安全·ecmascript·xss
ConardLi5 小时前
Chrome:新的滚动捕捉事件助你实现更丝滑的动画效果!
前端·javascript·浏览器
ConardLi5 小时前
安全赋值运算符,新的 JavaScript 提案让你告别 trycatch !
前端·javascript