前端大表单的设计思路

2,342 阅读3分钟

巨大的表单,在复杂的管理后台中最为常见。

什么叫大表单呢?

1、字段多

2、结构复杂

3、各种交互

就相当于网页上的银行单吧,并且有各类交互(增删改查)、校验。

由于近期做的这类表单较多,作此篇,权当总结与分享。

我相信此时的你使用的前端框架也是基于mvvm思想的框架(如vue、react等)。

所以,还得先简短发表一下我对mvvm的理解。

首先,mvvm的推崇不是毫无逻辑的,用的人多,自然说明用的舒服。

拆解:m(model)、v(view)、vm(viewModel)。

m与v是死的,vm是活的。vm就是核心,中枢神经。

由于框架的处理,vm的变动会直接体现在m与v中。

也就是说,页面交互逻辑、页面数据其实是通过控制vm来实现的。

(react的state、props,vue中的model、props都可以成为vm角色)

因此,我对大表单的设计会围绕着vm来进行。

对于大部分情况,我们会将vm直接定义成一个对象,将所有的字段都写进去。

编写view部分,也就是切图部分。每一个模块切一片,将vm里的字段对应的写进去。

但是我更倾向于页面可配置化的写法。

将页面中所有的字段定义为一个config对象,这个config对象包含了字段所有的信息(理想状态)。

{
    key: 'chineseName',
    value: null,
    label: '公司名称(中文)',
    type: 'input',
    config: {
        isRequested: true,
        validReg: /^[\u4e00-\u9fa5\s]+$/,
        validMsg: '请输入纯中文!'
    }
},
{
    key: 'companyType',
    value: 1,
    label: '公司类型',
    type: 'select',
    config: {
        isRequested: true,
        options: companyTypeArray()
    }
}

比如是input还是select,或者checkbox单选或者多选等等。

以及字段的label校验规则等。

基于这个config,可以编写函数提取出我们需要的vm对象。

// 获取数据模型
getModuleObj: arr => {
    return arr.reduce((obj, item) => {
        obj[item.key] = item.value
        return obj
    }, {})
}

我觉得比较重要的是,我从一个config中,就能看出整个页面的逻辑与数据。

当需要修改、新增、删除时,只需要操作config就行了。

这是第一步,确定好config的思路后,进入我认为大表单最重要的部分。

与接口数据的交互。

vm是我们页面展示的数据,传给api的,是另一个数据。

两者在层级结构上是类似的。

这里不应该有太大差异。如果差异太大,说明一开始字段定义的时候前端并没有参与。

fn1(vmData) -> apiData

比如这里我需要将数组转换为|分隔的字符串

// 递归处理modelData数据 modelData => apiData
const setParam = data => {
    if (data instanceof Array) {
        if (data.length > 0) {
            if (data[0] instanceof Object) {
                for (let i = 0; i < data.length; i++) {
                    data[i] = setParam(data[i])
                }
            } else {
                data = '|' + data.join('|') + '|'
                return data
            }
        } else {
            data = '||'
        }
    } else if (data instanceof Object) {
        for (let k in data) {
            data[k] = setParam(data[k])
        }
    }
    return data
}

fn2(apiData) -> vmData

只需要编写两个函数做数据的转换即可,层级较深可用递归处理。

总结一下,我这里对大表单的处理,其实就两点。

1、config描述文件(vm、view以此配置)

2、vm、apiData的相互转换(数据录入与数据回显)

能妥善处理好这两个问题,基本上大表单也就处理好了,剩下的就是细节的打磨。