文档驱动 —— 表单组件(二):meta生成器,告别书写代码


手写代码?

meta(json)需要手写吗?别闹,手写多麻烦呀,我这么懒怎么可能手写,这辈子都别想,所以要弄个工具出来,咱们说干就干。

这个工具,说白了本身就是一个表单,一个meta属性对应一个meta的属性,合在一起就是一个完整的meta了,只是不同的组件属性不同,需要区分对待不能混为一谈。
先看看工具啥样的
【工具截图】

是不是挺难看?我没有艺术细胞,大家多担待。等找到支持3.0的UI,就可以做一个漂亮的页面了,现在先实现功能。
左面是表单,右面是控件展示、控件值以及生成的meta。

流程

  1. 父级把需要生成的meta,通过属性传递进来,
  2. 把属性值设置给内部的固定meta,
  3. 根据控件类型筛选出来需要的属性。
  4. 然后依据固定meta生成表单,显示需要的属性。
  5. 填写内容生成需要的json

前四步都是内部流程,不用管,只需要第五步填内容即可。

代码

鸡生蛋还是蛋生鸡?

想做一个工具生成meta,然后这个工具还想用meta绑定的方式来做。
似乎是个死循环。

meta

破解之法就是,先写个简洁的meta

   {
        "101": {  
          "controlId": 101,
          "colName": "controlId",
          "controlType": 101,
        }
    }

然后复制三份,用这三个先绑定出来一个表单,然后在加属性,在绑定表单,一层一层循环出来的。

    {
        "101": {  
          "controlId": 101,
          "colName": "controlId",
          "controlType": 131,
          "isClear": false,
          "defaultValue": "",
          "autofocus": false,
          "disabled": false,
          "required": true,
          "readonly": false,
          "pattern": "",
          "class": "",
          "placeholder": "请输入组件编号",
          "title": "组件编号",
          "autocomplete": "on",
          "min": "0",
          "max": "9999",
          "step": "1"
        }

这是一个完整的meta,把一个表单需要的meta都筹齐了就可以召唤神龙了。好吧,是创建表单。

表单代码


用v-for循环,把表单循环出来,我这么懒,才不会一行一行的写tr呢。
因为每种组件需要的属性不同,所以需要做个数组存放组件需要的属性的ID,这样循环数组即可绑定出来需要的属性了。

meta的模板


这是生成需要的json的模板,直接用模板的方式来实现,这样可以根据需要调整格式。
比如json文件要求key要用双引号引起来,而js里面key就不需要双引号,
而eslint又要求字符串只能用单引号。
要求不一样怎么办?做不同的模板呗。

data

data: function () {
    return {
      testValue: '测试',
      helpMeta: {}, // 创建表单需要的meta
      baseMeta: { // 固定属性的
        controlId: 101,
        colName: 'abc',
        controlType: 101,
        isClear: true,
        defaultValue: '',
        autofocus: false,
        disabled: false,
        required: true,
        readonly: false,
        pattern: '',
        class: '',
        placeholder: '请输入',
        title: '',
        autocomplete: 'on',
        size: 10,
        maxlength: 10,
        min: 0,
        max: 9999,
        step: 1,
        rows: 5,
        cols: 50,
        optionKey: 'beixuan',
        optionList: []
      },
      tmpMeta: {}, // 按需生成属性的
      trList: [103],
      type: {}, // 各种组件类型需要的属性ID数组
      numberList: []
    }
  }
created: function () {
    // 读取json
    const json = require('@/components/metahelp.json')
    // 给data赋值
    this.helpMeta = json.helpMeta
    this.helpMeta[103].optionList = json.dic.ControlTypeList
    this.type = json.type
    this.trList = this.type[103] // 默认使用文本框的属性
  }

发现个问题,在setup里面似乎无法读取属性(prop)的值,所以还是用data、created 的方式来做。

变幻

  methods: {
    sendValue: function (value, colName) {
      // 根据字段名判断,设置需要的属性
      if (colName === 'controlType') {
        this.trList = this.type[value]
      }
      // 给对应字段赋值
      this.baseMeta[colName] = value

      // 根据类型拼接对象
      this.tmpMeta = {}
      for (var i = 0; i < this.trList.length; i += 1) {
        var item = this.trList[i]
        var key = this.helpMeta[item].colName
        this.tmpMeta[key] = this.baseMeta[key]
      }
      // 提交给父级组件
      this.$emit('update:modelValue', this.tmpMeta)
    }
  }

这个是依据组件类型拼接需要的属性,然后提交给父级组件的代码
这段确实有点绕,自己都晕。因为我懒,不想写那么多代码。

one more thing

写这段代码,花了好长时间,主要是对vue不太熟悉,另外上了点年龄,反应有点慢。
写这篇博客一比较卡文,原因就是思路很混乱,这个就比较狠危险了。

对了,完整代码在这里: https://github.com/naturefwvue/nfComponents

相关