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

相关推荐
拓端研究室39 分钟前
视频讲解:门槛效应模型Threshold Effect分析数字金融指数与消费结构数据
前端·算法
工一木子2 小时前
URL时间戳参数深度解析:缓存破坏与前端优化的前世今生
前端·缓存
半点寒12W3 小时前
微信小程序实现路由拦截的方法
前端
某公司摸鱼前端4 小时前
uniapp socket 封装 (可拿去直接用)
前端·javascript·websocket·uni-app
要加油哦~4 小时前
vue | 插件 | 移动文件的插件 —— move-file-cli 插件 的安装与使用
前端·javascript·vue.js
小林学习编程4 小时前
Springboot + vue + uni-app小程序web端全套家具商场
前端·vue.js·spring boot
柳鲲鹏4 小时前
WINDOWS最快布署WEB服务器:apache2
服务器·前端·windows
weixin-a153003083165 小时前
【playwright篇】教程(十七)[html元素知识]
java·前端·html
ai小鬼头6 小时前
AIStarter最新版怎么卸载AI项目?一键删除操作指南(附路径设置技巧)
前端·后端·github
一只叫煤球的猫6 小时前
普通程序员,从开发到管理岗,为什么我越升职越痛苦?
前端·后端·全栈