21

meta生成器 —— 表单元素组件

 3 years ago
source link: http://www.cnblogs.com/jyk/p/13653501.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

手写代码?

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

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

先看看工具啥样的

【工具截图】

eiMVVfU.jpg!mobile

是不是挺难看?我没有艺术细胞,大家多担待。等找到支持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;width: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;width:400px;float:left;">
      <!--效果和json-->
      测试:<nfInput v-model="testValue" :meta="baseMeta"  /> ==》 {{testValue}}
      <div align="left" style="padding:15px;background-color:#FFEEEE;height:400px;width:400px;clear:both">
        {<br>
          <span v-for="(item, key, index) in tmpMeta" :key="index">
            <span v-if="typeof item === 'number' && !isNaN(item)">  "{{key}}": {{item}}, <br></span>
            <span v-if="typeof item === 'string'">  "{{key}}": "{{item}}", <br></span>
            <span v-if="typeof(item) ==='boolean'">  "{{key}}": {{item}}, <br></span>
            <span v-if="typeof(item) ==='object'">
                "{{key}}": [<br>
              <span v-for="(opt, index) in item" :key="'opt'+index">    {{opt}}, <br></span>
                ]<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


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK