zoukankan      html  css  js  c++  java
  • 文档驱动 —— 表单组件(二):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都筹齐了就可以召唤神龙了。好吧,是创建表单。

    表单代码

    <template>
      <div class="home">
        <div><h1>表单元素组件meta生成工具</h1></div>
        <div style="background-color:#dddddd;height:600px;400px;float:left;">
          <!--表单-->
          <table>
            <tr v-for="(key,index) in trList" :key="index"><!--遍历需要的meta-->
              <td align="right">{{helpMeta[key].colName}}:<!--名称-->
              </td>
              <td align="left"><!--控件-->
                <nfInput :modelValue="modelValue[helpMeta[key].colName]" :meta="helpMeta[key]" @getvalue="sendValue"/>
                {{helpMeta[key].title}}
              </td>
            </tr>
          </table>
        </div>
      </div>
    </template>
    

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

    meta的模板

    <template>
      <div class="home">
        <div align="left" style="padding:5px;background-color:#FFFFEE;height:600px;400px;float:left;">
          <!--效果和json-->
          测试:<nfInput v-model="testValue" :meta="baseMeta"  /> ==》 {{testValue}}
          <div align="left" style="padding:15px;background-color:#FFEEEE;height:400px;400px;clear:both">
            {<br>
              <span v-for="(item, key, index) in tmpMeta" :key="index">
                <span v-if="typeof item === 'number' && !isNaN(item)">&nbsp;&nbsp;"{{key}}": {{item}}, <br></span>
                <span v-if="typeof item === 'string'">&nbsp;&nbsp;"{{key}}": "{{item}}", <br></span>
                <span v-if="typeof(item) ==='boolean'">&nbsp;&nbsp;"{{key}}": {{item}}, <br></span>
                <span v-if="typeof(item) ==='object'">
                  &nbsp;&nbsp;"{{key}}": [<br>
                  <span v-for="(opt, index) in item" :key="'opt'+index">&nbsp;&nbsp;&nbsp;&nbsp;{{opt}}, <br></span>
                  &nbsp;&nbsp;]<br>
                </span>
              </span>
            }
          </div>
        </div>
      </div>
    </template>
    

    这是生成需要的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

  • 相关阅读:
    文件上传和多线程通信
    黏包
    socket通信
    osi七层协议
    面向对象的反射和双下方法
    类的成员和异常处理
    python面向对象类的约束和设计的统一化规范
    单继承和多继承
    对象
    Python-----带参数的装饰器以及补充
  • 原文地址:https://www.cnblogs.com/jyk/p/13653501.html
Copyright © 2011-2022 走看看