文檔驅動 —— 表單組件(二):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;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)">&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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM