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 小时前
unity关于自定义渲染、内存管理、性能调优、复杂物理模拟、并行计算以及插件开发
前端·unity·c#
Devil枫3 小时前
Vue 3 单元测试与E2E测试
前端·vue.js·单元测试
尚梦4 小时前
uni-app 封装刘海状态栏(适用小程序, h5, 头条小程序)
前端·小程序·uni-app
GIS程序媛—椰子5 小时前
【Vue 全家桶】6、vue-router 路由(更新中)
前端·vue.js
前端青山5 小时前
Node.js-增强 API 安全性和性能优化
开发语言·前端·javascript·性能优化·前端框架·node.js
毕业设计制作和分享5 小时前
ssm《数据库系统原理》课程平台的设计与实现+vue
前端·数据库·vue.js·oracle·mybatis
清灵xmf7 小时前
在 Vue 中实现与优化轮询技术
前端·javascript·vue·轮询
大佩梨7 小时前
VUE+Vite之环境文件配置及使用环境变量
前端
GDAL7 小时前
npm入门教程1:npm简介
前端·npm·node.js
小白白一枚1118 小时前
css实现div被图片撑开
前端·css