如何手写一个JSON转table的功能

114 阅读1分钟

最近有一个新需求,就是用户通过一个输入框,输入一段JSON,然后我们需要把用户的JSON转化成表格的格式,方便给用户查看对应的关系,如图所示:

image.png

然后我们需要一个输入框

<el-input type="textarea" style="width:100%;flex: 1;overflow-y: auto" v-model="json" class="textarea" :autosize="{ minRows: 15, maxRows: 30 }" placeholder="请输入json字符串" @change="whenJsonChange"></el-input>
<span style="color:red" v-show="jsonError">您输入的不是一个正确的json</span>

然后我们需要一个展示的表格

<el-table
  :data="tableData"
  style="width: 100%;flex:1"
  row-key="rowId"
  border
  default-expand-all
  height="0"
  :tree-props="{children: 'children', hasChildren: 'hasChildren'}"
  :header-cell-style="{ background: '#fafafa' }"
>
  <el-table-column type="index" label="序号" width="55"  align="center"/>
  <el-table-column label="字段名称" prop="key" show-overflow-tooltip align="center"/>
  <el-table-column label="实例值" prop="value" show-overflow-tooltip align="center"/>

</el-table>

然后在js里面

export default {
  name: "JsonToTree",
  components: {},
  data () {
   return {
    json:null,
    tableData:[],
    jsonError:false,
   }
  },
  created () {
   this.whenJsonChange();
  },
  methods: {
   whenJsonChange() {
    this.jsonError = false;
    let obj;
    try {
     obj = new Function(`return ${this.json}`)();
    } catch (e) {
     this.jsonError = true;
    }
    if (typeof obj === 'object' && obj) {
     this.tableData = this.convertToTreeTable(obj);
     console.log(this.tableData)
    } else {
     this.tableData = [];
     this.jsonError = true;
    }
   },
   //生成随机的id
   createId(length) {
    let returnStr = '';
    const charStr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    for (let i = 0; i < length; i++) {
     let index = Math.round(Math.random() * (charStr.length - 1));
     if (i === 0) {
      index = Math.round(Math.random() * (charStr.length - 11));
     }
     returnStr += charStr.substring(index, index + 1);
    }
    return returnStr;
   },
   //判断数据是否是数组或者对象
   isArrayOrObj(data) {
    return data instanceof Array||data instanceof Object;
   },
   //obj是数组或者对象
   convertToTreeTable(obj,lastKey='') {
    if (Array.isArray(obj)) {
     return obj.reduce((acc, cur) => {
      let accList=this.convertToTreeTable(cur,lastKey)
      accList&&acc.push(...accList)
      return acc;
     }, [])
     //return obj.map(t => this.convertToTreeTable(t));
    } else if (obj instanceof Object) {
     return Object.entries(obj).map(([key, value]) => {
      const isSimple = !this.isArrayOrObj(value);
      const temp = {
       rowId: this.createId(15),
       key,
       children: []
      };
      if (lastKey) {
       temp.groupKey = `${lastKey}.${key}`;
      }else{
       temp.groupKey = key;
      }
      if (isSimple) {
       temp.value = value;
      } else {
       if(Array.isArray(value)&&!this.isArrayOrObj(value[0])){
        temp.value=value.join(',')
       }else{
        let children = this.convertToTreeTable(value,key);
        while (children?.length === 1 && Array.isArray(children[0])) {
         children = children[0];
        }
        temp.children = children;
        temp.value =temp.children.length > 0 ? '见子列表' : '-';
       }
      }
      return temp;
     });
    }
   }
  },
 
}