神刀安全网

JSON Schema 表单

前端的同学对 JSON 都应该是非常熟悉的,所以今天我们讨论的问题应该是很好理解的。

先来看下 JSON Schema 这个东西,我直接引用官网的描述。

JSON Schema is a vocabulary that allows you to annotate and validate JSON documents.

英文很烂的我自然是看不懂的,所以我再直接引用翻译软件的翻译。

JSON模式是一个允许您注释和验证JSON文档的词汇。

翻译的也还是看不懂的,但是大概能理解JSON Schema的意思,也就是一个JSON文档可以用另一个JSON去描述。

举一个简单的栗子:

//这是一个 JSON 文档 {     "name": "zhuss" } //这是描述上面 JSON 的文档 {    "type":"object",    "properties":{         "name":{             "type":"string"         }     } }

栗子说明了概念就是这么简单,那如何在实际的中使用到这个东西,在什么时候可以用到这样的东西呢,感觉好像没有什么地方能够用到这样的技术呀。

答案是,有些比较简单数据需要运营配置的时候,但是运营是不会写JSON文档的,必须做成可视化的表单,运营才会填相应的数据。但是,我们不想花时间针对每个配置写一个表单页面,所以就可以运用上面的概念,做一个一劳永逸的模板,我们(程序员哥哥)写好 JSON Schema,对应生成一个表单让运营去填,提交的表单就是一个 JSON 文档了。

GitHub 上关于 jsonschema-form 的项目是这个react-jsonschema-form

如果我们不是 react 项目,而且我们用的 ui 框架bootstrap怎么办?其实我们可以在项目中简单的使用 JSON Schema 来完成我们的需求。

比如我用 Vue.js,ui用的是ElementUI,实现简单的 JSON Schema Form模板。

首先,确定我们的 JSON 文档是简单形式的,最多嵌套一层数组。因为表单的形式输出的 JSON 文档一般都是单层的JSON,如果层级多了,那这个表单就无法组织了。

我们准备一份需要的JSON文档,对应的输出一份JSON Schema文档。

//json文档 {     "title": "标题",     "tasks": [         {             "title": "名称",             "details": "13123",             "done": true         }     ] }  //对应的Schema文档 {     "title": "测试配置",     "type": "object",     "required": [         "title"     ],     "properties": {         "title": {             "type": "string",             "title": "Task list title"         },         "tasks": {             "type": "array",             "title": "Tasks",             "items": {                 "type": "object",                 "required": [                     "title"                 ],                 "properties": {                     "title": {                         "type": "string",                         "title": "Title",                         "description": "A sample title"                     },                     "details": {                         "type": "string",                         "title": "Task details",                         "description": "Enter the task details"                     },                     "done": {                         "type": "boolean",                         "title": "Done?",                         "default": false                     }                 }             }         }     } }

下面是我书写的一份Html 表单模板

<div class="form">       <el-form :model="formData">         <div v-for="(item,key) in jsonSchema.properties">           <!--单层-->           <el-form-item :label="item.title" v-if="item.type=='string'">             <el-input v-model="formData[key]"></el-input>           </el-form-item>           <el-form-item :label="item.title" v-if="item.type=='integer'">             <el-input v-model="formData[key]"></el-input>           </el-form-item>           <el-form-item :label="item.title" v-if="item.type==='boolean'">             <el-switch v-model="formData[key]"></el-switch>           </el-form-item>           <!--单层 end-->           <!--嵌套array-->           <div v-if="item.type==='array'">             <div class="array-title">               <p class="array-title-text">                 <span>{{item.title}}</span>               </p>               <p>                 <el-button @click="addBtnClick(item.items.properties,key)">+添加</el-button>               </p>             </div>             <div class="array-content" v-for="(initem,index) in formData[key]">               <!--array对象-->               <div class="array-obj">                 <div v-for="(i,k) in item.items.properties">                   <el-form-item :label="i.title" v-if="i.type==='string'">                     <el-input v-model="initem[k]"></el-input>                   </el-form-item>                   <el-form-item :label="i.title" v-if="i.type==='number'">                     <el-input-number v-model="initem[k]"></el-input-number>                   </el-form-item>                   <el-form-item :label="i.title" v-if="i.type==='boolean'">                     <el-switch v-model="initem[k]"></el-switch>                   </el-form-item>                 </div>               </div>               <!--array对象 end-->               <!--操作按钮-->               <div class="array-btns">                 <p>                   <el-button @click="moveBtnClick(index,index-1,key)" :disabled="index==0">上移</el-button>                 </p>                 <p>                   <el-button @click="moveBtnClick(index,index+1,key)" :disabled="index==formData[key].length-1">下移</el-button>                 </p>                 <p>                   <el-button @click="delBtnClicl(index,key)">删除</el-button>                 </p>               </div>               <!--操作按钮 end-->             </div>           </div>           <!--嵌套array end-->         </div>         <div style="padding-top:5px;">           <el-form-item>             <el-button @click="submitBtnClick">提交</el-button>           </el-form-item>         </div>       </el-form>     </div>     <!--form-->

如果是没有嵌套array的简单 JSON ,那简单不过了,但是难免会有嵌套的。值得注意的是嵌套,需要有一些按钮操作。

比如向array中添加对象,删除对象,移动对象顺序等。。。

//添加数组       addBtnClick(item, key) {         var obj = {};         for (var i in item) {           if (item[i].type == "boolean") {             obj[i] = false;           } else {             obj[i] = "";           }         }         if (this.formData[key]) {           this.formData[key].push(obj);         } else {           this.formData[key] = [];           this.formData[key].push(obj);         }         this.formData = this.formData;       },       //删除数组       delBtnClicl(index, key) {         this.formData[key].splice(index, 1);       },       //移动       moveBtnClick(firstIndex, lastIndex, key, ) {         var first = JSON.parse(JSON.stringify(this.formData[key][firstIndex]));         var last = JSON.parse(JSON.stringify(this.formData[key][lastIndex]));         for (var i in first) {           this.formData[key][lastIndex][i] = first[i];         };          for (var i in last) {           this.formData[key][firstIndex][i] = last[i];         }       }

最终渲染出来的模板下图所示:

JSON Schema 表单

Paste_Image.png

上诉例子简化了表单,如果可以,借鉴 react-jsonschema-form 是一个比较不错的选择。

转载本站任何文章请注明:转载至神刀安全网,谢谢神刀安全网 » JSON Schema 表单

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址