mirror of
https://github.com/Ssl1S/json-schema-editor-vue.git
synced 2025-12-30 01:37:55 +08:00
feat: 增加自定义基础属性的功能
This commit is contained in:
180
examples/App.vue
180
examples/App.vue
@@ -1,21 +1,37 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="app">
|
<div id="app">
|
||||||
<div class="title">
|
<div class="title">
|
||||||
<a href="https://github.com/zyqwst/json-schema-editor-vue" target="_blank">json-schema-editor-vue</a>
|
<a href="https://github.com/zyqwst/json-schema-editor-vue" target="_blank"
|
||||||
|
>json-schema-editor-vue</a
|
||||||
|
>
|
||||||
<span class="version"> version:{{ version }}</span>
|
<span class="version"> version:{{ version }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="desc">
|
<div class="desc">
|
||||||
<div>A json-schema editor of high efficient and easy-to-use, base on Vue.
|
<div>
|
||||||
|
A json-schema editor of high efficient and easy-to-use, base on Vue.
|
||||||
<a @click="visible = true">import json</a>
|
<a @click="visible = true">import json</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<codemirror class="code" v-model="jsonStr" :readOnly="false"/>
|
<codemirror class="code" v-model="jsonStr" :readOnly="false" />
|
||||||
<json-schema-editor class="schema" :value="tree" disabledType lang="zh_CN" custom/>
|
<json-schema-editor
|
||||||
|
class="schema"
|
||||||
|
:value="tree"
|
||||||
|
disabledType
|
||||||
|
lang="zh_CN"
|
||||||
|
custom
|
||||||
|
:extra="extraSetting"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<a-modal v-model="visible" title="import json" width="800px" height="600x" @ok="handleImportJson">
|
<a-modal
|
||||||
|
v-model="visible"
|
||||||
|
title="import json"
|
||||||
|
width="800px"
|
||||||
|
height="600x"
|
||||||
|
@ok="handleImportJson"
|
||||||
|
>
|
||||||
<div class="code-container">
|
<div class="code-container">
|
||||||
<codemirror class="code" v-model="importJson" :readOnly="false"/>
|
<codemirror class="code" v-model="importJson" :readOnly="false" />
|
||||||
</div>
|
</div>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
</div>
|
</div>
|
||||||
@@ -23,122 +39,132 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
var app = require("../package.json");
|
var app = require("../package.json");
|
||||||
import Codemirror from './components/Codemirror.vue'
|
import Codemirror from "./components/Codemirror.vue";
|
||||||
import GenerateSchema from 'generate-schema'
|
import GenerateSchema from "generate-schema";
|
||||||
export default {
|
export default {
|
||||||
name: 'App',
|
name: "App",
|
||||||
components: { Codemirror },
|
components: { Codemirror },
|
||||||
computed: {
|
computed: {
|
||||||
jsonStr: {
|
jsonStr: {
|
||||||
get: function () {
|
get: function () {
|
||||||
return JSON.stringify(this.tree, null, 2)
|
return JSON.stringify(this.tree, null, 2);
|
||||||
},
|
},
|
||||||
set: function (newVal) {
|
set: function (newVal) {
|
||||||
this.tree = JSON.parse(newVal)
|
this.tree = JSON.parse(newVal);
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
version: app.version,
|
version: app.version,
|
||||||
importJson: '',
|
importJson: "",
|
||||||
visible: false,
|
visible: false,
|
||||||
tree:
|
extraSetting: {
|
||||||
{
|
integer: {
|
||||||
"root": {
|
default: {
|
||||||
"type": "object",
|
name: "默认值",
|
||||||
"title": "条件",
|
type: "integer",
|
||||||
"properties": {
|
},
|
||||||
"name": {
|
},
|
||||||
"type": "string",
|
string: {
|
||||||
"title": "名称",
|
default: {
|
||||||
"maxLength": 10,
|
name: "默认值",
|
||||||
"minLength": 2
|
type: "integer",
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
"appId": {
|
tree: {
|
||||||
"type": "integer",
|
root: {
|
||||||
"title": "应用ID"
|
type: "object",
|
||||||
|
title: "条件",
|
||||||
|
properties: {
|
||||||
|
name: {
|
||||||
|
type: "string",
|
||||||
|
title: "名称",
|
||||||
|
maxLength: 10,
|
||||||
|
minLength: 2,
|
||||||
|
},
|
||||||
|
appId: {
|
||||||
|
type: "integer",
|
||||||
|
title: "应用ID",
|
||||||
|
default: 3,
|
||||||
|
},
|
||||||
|
credate: {
|
||||||
|
type: "string",
|
||||||
|
title: "创建日期",
|
||||||
|
format: "date",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
required: ["name", "appId", "credate"],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
"credate": {
|
};
|
||||||
"type": "string",
|
|
||||||
"title": "创建日期",
|
|
||||||
"format": "date"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"name",
|
|
||||||
"appId",
|
|
||||||
"credate"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
handleImportJson () {
|
handleImportJson() {
|
||||||
const t = GenerateSchema.json(JSON.parse(this.importJson))
|
const t = GenerateSchema.json(JSON.parse(this.importJson));
|
||||||
delete t.$schema
|
delete t.$schema;
|
||||||
this.tree.root = t
|
this.tree.root = t;
|
||||||
this.visible = false
|
this.visible = false;
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
*{
|
* {
|
||||||
padding:0;
|
padding: 0;
|
||||||
margin:0;
|
margin: 0;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
.title{
|
.title {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 40px;
|
font-size: 40px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
height:100px;
|
height: 100px;
|
||||||
line-height: 100px;
|
line-height: 100px;
|
||||||
}
|
}
|
||||||
.version{
|
.version {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
.desc{
|
.desc {
|
||||||
padding:20px;
|
padding: 20px;
|
||||||
width:80vw;
|
width: 80vw;
|
||||||
min-width:800px;
|
min-width: 800px;
|
||||||
margin:auto;
|
margin: auto;
|
||||||
padding: 0 3em;
|
padding: 0 3em;
|
||||||
font-size: 1.2em;
|
font-size: 1.2em;
|
||||||
}
|
}
|
||||||
.container{
|
.container {
|
||||||
display: flex;
|
display: flex;
|
||||||
padding:20px;
|
padding: 20px;
|
||||||
width:80vw;
|
width: 80vw;
|
||||||
min-width:800px;
|
min-width: 800px;
|
||||||
justify-content:center;
|
justify-content: center;
|
||||||
height: calc(100vh - 150px);
|
height: calc(100vh - 150px);
|
||||||
margin:auto;
|
margin: auto;
|
||||||
}
|
}
|
||||||
.code-container{
|
.code-container {
|
||||||
max-height: 600px;
|
max-height: 600px;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
.schema{
|
.schema {
|
||||||
margin-left: 20px;
|
margin-left: 20px;
|
||||||
width:50%;
|
width: 50%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
overflow-x:hidden;
|
overflow-x: hidden;
|
||||||
border:1px solid rgba(0,0,0,.1);
|
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
padding: 12px;
|
padding: 12px;
|
||||||
}
|
}
|
||||||
.CodeMirror {
|
.CodeMirror {
|
||||||
height: 100% !important;
|
height: 100% !important;
|
||||||
}
|
}
|
||||||
.vue-codemirror{
|
.vue-codemirror {
|
||||||
flex:1;
|
flex: 1;
|
||||||
margin: 0 24px;
|
margin: 0 24px;
|
||||||
border: 1px solid rgba(0,0,0,.1);
|
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||||
min-height:300px;
|
min-height: 300px;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ const langs = {
|
|||||||
'cancel':'Cancel',
|
'cancel':'Cancel',
|
||||||
'minLength':'Min length',
|
'minLength':'Min length',
|
||||||
'maxLength': 'Max length',
|
'maxLength': 'Max length',
|
||||||
'pattern':'MUST be a valid regular expression.',
|
'pattern':'Must be a valid regular expression.',
|
||||||
'exclusiveMinimum': 'Value strictly less than',
|
'exclusiveMinimum': 'Value strictly less than',
|
||||||
'exclusiveMaximum': 'Value strictly more than',
|
'exclusiveMaximum': 'Value strictly more than',
|
||||||
'minimum': 'Min',
|
'minimum': 'Min',
|
||||||
|
|||||||
@@ -61,7 +61,7 @@
|
|||||||
<a-row :gutter="6">
|
<a-row :gutter="6">
|
||||||
<a-col :span="8" v-for="(item,key) in advancedValue" :key="key">
|
<a-col :span="8" v-for="(item,key) in advancedValue" :key="key">
|
||||||
<a-form-item>
|
<a-form-item>
|
||||||
<span>{{ local[key] }}</span>
|
<span>{{ advancedAttr[key].extra ? (lang=='en_US'? key : advancedAttr[key].name):local[key] }}</span>
|
||||||
<a-input-number v-model="advancedValue[key]" v-if="advancedAttr[key].type === 'integer' || advancedAttr[key].type === 'number'" style="width:100%" :placeholder="key"/>
|
<a-input-number v-model="advancedValue[key]" v-if="advancedAttr[key].type === 'integer' || advancedAttr[key].type === 'number'" style="width:100%" :placeholder="key"/>
|
||||||
<span v-else-if="advancedAttr[key].type === 'boolean'" style="display:inline-block;width:100%">
|
<span v-else-if="advancedAttr[key].type === 'boolean'" style="display:inline-block;width:100%">
|
||||||
<a-switch v-model="advancedValue[key]"/>
|
<a-switch v-model="advancedValue[key]"/>
|
||||||
@@ -115,7 +115,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import { isNull, renamePropertyAndKeepKeyPrecedence } from './util'
|
import { isNull, renamePropertyAndKeepKeyPrecedence, arrayDifference } from './util'
|
||||||
import {TYPE_NAME, TYPE} from './type/type'
|
import {TYPE_NAME, TYPE} from './type/type'
|
||||||
import { Row,Col,Button,Input,InputNumber, Icon,Checkbox,Select,Tooltip,Modal,Form,Switch} from 'ant-design-vue'
|
import { Row,Col,Button,Input,InputNumber, Icon,Checkbox,Select,Tooltip,Modal,Form,Switch} from 'ant-design-vue'
|
||||||
import LocalProvider from './LocalProvider'
|
import LocalProvider from './LocalProvider'
|
||||||
@@ -173,6 +173,10 @@ export default {
|
|||||||
lang: { // i18n language
|
lang: { // i18n language
|
||||||
type: String,
|
type: String,
|
||||||
default: 'zh_CN'
|
default: 'zh_CN'
|
||||||
|
},
|
||||||
|
extra: { // 基础设置里追加的设置
|
||||||
|
type: Object,
|
||||||
|
default: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -236,7 +240,28 @@ export default {
|
|||||||
local: LocalProvider(this.lang)
|
local: LocalProvider(this.lang)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
mounted () {
|
||||||
|
this.init()
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
init(){
|
||||||
|
if (!this.extra || JSON.stringify(this.extra) === '{}') return
|
||||||
|
|
||||||
|
const keys = Object.keys(this.extra)
|
||||||
|
const nonCompliant = arrayDifference(TYPE_NAME, keys);
|
||||||
|
if (nonCompliant.length>0 ){
|
||||||
|
console.warn('not compliant extra,Supports only the following keys:string, number, integer,object, array, boolean' ,nonCompliant);
|
||||||
|
}
|
||||||
|
for(let item in this.extra){
|
||||||
|
const setting = this.extra[item]
|
||||||
|
const basicSetting = TYPE[item]
|
||||||
|
Object.entries(setting).forEach(([key, value]) => {
|
||||||
|
value.extra=true
|
||||||
|
basicSetting.attr[key] = value
|
||||||
|
basicSetting.value[key] = null
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
onInputName(e){
|
onInputName(e){
|
||||||
const oldKey = this.pickKey
|
const oldKey = this.pickKey
|
||||||
const newKey = e.target.value
|
const newKey = e.target.value
|
||||||
|
|||||||
@@ -39,4 +39,8 @@ export function renamePropertyAndKeepKeyPrecedence(_this, obj, [oldKey, newKey])
|
|||||||
}, obj)
|
}, obj)
|
||||||
}
|
}
|
||||||
return obj
|
return obj
|
||||||
|
}
|
||||||
|
/**过滤数组元素 */
|
||||||
|
export function arrayDifference(basicArr, arr) {
|
||||||
|
return arr.filter(item => !basicArr.includes(item));
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user