mirror of
https://github.com/Ssl1S/json-schema-editor-vue.git
synced 2025-12-30 01:37:55 +08:00
Merge branch '2.0.0'
This commit is contained in:
@@ -1,20 +1,45 @@
|
||||
<template>
|
||||
<div id="app">
|
||||
<div class="title">
|
||||
Demo
|
||||
<div class="title">
|
||||
<a href="https://github.com/zyqwst/json-schema-editor-vue" target="_blank">json-schema-editor-vue</a> Preview
|
||||
</div>
|
||||
<div class="desc">
|
||||
<div>A json-schema editor of high efficient and easy-to-use, base on Vue.
|
||||
<a @click="visible = true">import json</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container">
|
||||
<pre>{{tree}}</pre>
|
||||
<codemirror class="code" v-model="jsonStr" :readOnly="false"/>
|
||||
<json-schema-editor class="schema" :value="tree" disabledType lang="zh_CN" custom/>
|
||||
</div>
|
||||
<a-modal v-model="visible" title="import json" width="800px" height="600x" @ok="handleImportJson">
|
||||
<div class="code-container">
|
||||
<codemirror class="code" v-model="importJson" :readOnly="false"/>
|
||||
</div>
|
||||
</a-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Codemirror from './components/Codemirror.vue'
|
||||
import GenerateSchema from 'generate-schema'
|
||||
export default {
|
||||
name: 'App',
|
||||
components: { Codemirror },
|
||||
computed: {
|
||||
jsonStr: {
|
||||
get: function () {
|
||||
return JSON.stringify(this.tree, null, 2)
|
||||
},
|
||||
set: function (newVal) {
|
||||
this.tree = JSON.parse(newVal)
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
importJson: '',
|
||||
visible: false,
|
||||
tree:
|
||||
{
|
||||
"root": {
|
||||
@@ -45,6 +70,14 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleImportJson () {
|
||||
const t = GenerateSchema.json(JSON.parse(this.importJson))
|
||||
delete t.$schema
|
||||
this.tree.root = t
|
||||
this.visible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -61,6 +94,14 @@ export default {
|
||||
height:100px;
|
||||
line-height: 100px;
|
||||
}
|
||||
.desc{
|
||||
padding:20px;
|
||||
width:80vw;
|
||||
min-width:800px;
|
||||
margin:auto;
|
||||
padding: 0 3em;
|
||||
font-size: 1.2em;
|
||||
}
|
||||
.container{
|
||||
display: flex;
|
||||
padding:20px;
|
||||
@@ -70,14 +111,9 @@ export default {
|
||||
height: calc(100vh - 150px);
|
||||
margin:auto;
|
||||
}
|
||||
.container>pre {
|
||||
font-family: monospace;
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
border:1px solid rgba(0,0,0,.1);
|
||||
border-radius: 8px;
|
||||
padding: 12px;
|
||||
width:50%
|
||||
.code-container{
|
||||
max-height: 600px;
|
||||
overflow: auto;
|
||||
}
|
||||
.schema{
|
||||
margin-left: 20px;
|
||||
@@ -89,4 +125,15 @@ export default {
|
||||
border-radius: 8px;
|
||||
padding: 12px;
|
||||
}
|
||||
.CodeMirror {
|
||||
height: 100% !important;
|
||||
}
|
||||
.vue-codemirror{
|
||||
flex:1;
|
||||
margin: 0 24px;
|
||||
border: 1px solid rgba(0,0,0,.1);
|
||||
min-height:300px;
|
||||
overflow: auto;
|
||||
border-radius: 6px;
|
||||
}
|
||||
</style>
|
||||
|
||||
58
examples/components/Codemirror.vue
Normal file
58
examples/components/Codemirror.vue
Normal file
@@ -0,0 +1,58 @@
|
||||
<template>
|
||||
<codemirror v-model="content" :options="cmOptions" />
|
||||
</template>
|
||||
<script>
|
||||
import { codemirror } from 'vue-codemirror'
|
||||
import 'codemirror/lib/codemirror.css'
|
||||
import 'codemirror/theme/idea.css'
|
||||
import 'codemirror/theme/duotone-light.css'
|
||||
import 'codemirror/mode/javascript/javascript.js'
|
||||
import 'codemirror/mode/sql/sql.js'
|
||||
export default {
|
||||
components: { codemirror },
|
||||
props: {
|
||||
readOnly: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
mode: {
|
||||
type: String,
|
||||
default: 'text/javascript'
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
theme: {
|
||||
type: String,
|
||||
default: 'idea'
|
||||
},
|
||||
lineNumbers: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
value: {
|
||||
handler: function (newVal) {
|
||||
this.content = newVal
|
||||
}
|
||||
},
|
||||
content: function (newVal) {
|
||||
this.$emit('input', newVal)
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
content: this.value,
|
||||
cmOptions: {
|
||||
tabSize: 2,
|
||||
mode: this.mode,
|
||||
theme: this.theme,
|
||||
lineNumbers: this.lineNumbers,
|
||||
readOnly: this.readOnly
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,7 +1,9 @@
|
||||
import Vue from 'vue'
|
||||
import App from './App.vue'
|
||||
import JsonSchemaEditor from '../packages/index'
|
||||
import { Modal } from 'ant-design-vue'
|
||||
Vue.config.productionTip = false
|
||||
Vue.use(Modal)
|
||||
Vue.use(JsonSchemaEditor)
|
||||
|
||||
new Vue({
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
285
lib/json-schema-editor-vue.umd.min.js
vendored
285
lib/json-schema-editor-vue.umd.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "json-schema-editor-vue",
|
||||
"version": "1.2.5",
|
||||
"version": "2.0.0",
|
||||
"author": "zhangyq",
|
||||
"description": "A json-schema editor of high efficient and easy-to-use, base on Vue",
|
||||
"keywords": [
|
||||
@@ -27,7 +27,9 @@
|
||||
"dependencies": {
|
||||
"ant-design-vue": "^1.7.2",
|
||||
"core-js": "^3.6.5",
|
||||
"vue": "^2.6.11"
|
||||
"generate-schema": "^2.6.0",
|
||||
"vue": "^2.6.11",
|
||||
"vue-codemirror": "^4.0.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vue/cli-plugin-babel": "~4.4.0",
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
<template v-if="isArray">
|
||||
<json-schema-editor :value="{items:pickValue.items}" :deep="deep+1" disabled isItem :root="false" class="children" :lang="lang" :custom="custom"/>
|
||||
</template>
|
||||
<a-modal v-model="modalVisible" :title="local['adv_setting']" :maskClosable="false" :okText="local['ok']" :cancelText="local['cancel']" width="800px" @ok="handleOk" dialogClass="json-schema-editor-advanced-modal">
|
||||
<a-modal v-model="modalVisible" v-if="modalVisible" :title="local['adv_setting']" :maskClosable="false" :okText="local['ok']" :cancelText="local['cancel']" width="800px" @ok="handleOk" dialogClass="json-schema-editor-advanced-modal">
|
||||
<h3 v-text="local['base_setting']">基础设置</h3>
|
||||
<a-form v-model="advancedValue" class="ant-advanced-search-form">
|
||||
<a-row :gutter="6">
|
||||
@@ -101,7 +101,7 @@
|
||||
</a-col>
|
||||
<a-col :span="8">
|
||||
<a-form-item>
|
||||
<a-button icon="check" type="link" @click="confirmAddCustomNode" v-if="customing"></a-button>
|
||||
<a-button icon="check" type="link" @click="confirmAddCustomNode(null)" v-if="customing"></a-button>
|
||||
<a-tooltip :title="local['add_custom']" v-else>
|
||||
<a-button icon="plus" type="link" @click="addCustomNode"></a-button>
|
||||
</a-tooltip>
|
||||
@@ -115,11 +115,12 @@
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import Vue from 'vue'
|
||||
import { isNull } from './util'
|
||||
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 LocalProvider from './LocalProvider'
|
||||
Modal.install(Vue)
|
||||
export default {
|
||||
name:'JsonSchemaEditor',
|
||||
components: {
|
||||
@@ -226,28 +227,37 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
parseCustomProps () {
|
||||
const ownProps = [ 'type', 'title', 'properties', 'items', ...Object.keys(this.advancedAttr)]
|
||||
Object.keys(this.pickValue).forEach(key => {
|
||||
ownProps.indexOf(key) === -1 && this.confirmAddCustomNode({ key: key, value: this.pickValue[key] })
|
||||
})
|
||||
},
|
||||
onInputName(e){
|
||||
const val = e.target.value
|
||||
const p = {};
|
||||
for(let key in this.parent.properties){
|
||||
if(key != this.pickKey){
|
||||
p[key] = this.parent.properties[key]
|
||||
}else{
|
||||
p[val] = this.parent.properties[key]
|
||||
delete this.parent.properties[key]
|
||||
}
|
||||
}
|
||||
this.$set(this.parent,'properties',p)
|
||||
// 删掉无效的required
|
||||
const requireds = this.parent.required
|
||||
if(requireds && requireds.length > 0) {
|
||||
this.$set(this.parent,'required', requireds.filter(item => p[item]))
|
||||
const oldKey = this.pickKey
|
||||
const newKey = e.target.value
|
||||
if(oldKey === newKey) return
|
||||
|
||||
const nodeValue = this.parent.properties[oldKey]
|
||||
|
||||
// 替换key名
|
||||
this.$delete(this.parent.properties, oldKey)
|
||||
this.$set(this.parent.properties, newKey, nodeValue)
|
||||
|
||||
// required重新设置
|
||||
const requireds = this.parent.required || []
|
||||
const oldIndex = requireds.indexOf(oldKey)
|
||||
if(requireds.length > 0 && oldIndex > -1) {
|
||||
requireds.splice(oldIndex, 1)
|
||||
requireds.push(newKey)
|
||||
this.$set(this.parent,'required', [...new Set(requireds)])
|
||||
}
|
||||
},
|
||||
onChangeType() {
|
||||
this.$delete(this.pickValue,'properties')
|
||||
this.$delete(this.pickValue,'items')
|
||||
this.$delete(this.pickValue,'required')
|
||||
this.$delete(this.pickValue,'format')
|
||||
if(this.isArray){
|
||||
this.$set(this.pickValue,'items',{type:'string'})
|
||||
}
|
||||
@@ -256,8 +266,7 @@ export default {
|
||||
this._checked(e.target.checked,this.parent)
|
||||
},
|
||||
onRootCheck(e){
|
||||
const checked = e.target.checked
|
||||
this._deepCheck(checked,this.pickValue)
|
||||
this._deepCheck( e.target.checked,this.pickValue)
|
||||
},
|
||||
_deepCheck(checked,node){
|
||||
if(node.type === 'object' && node.properties){
|
||||
@@ -294,8 +303,9 @@ export default {
|
||||
this.$set(this.addProp,'value','')
|
||||
this.customing = true
|
||||
},
|
||||
confirmAddCustomNode() {
|
||||
this.customProps.push(this.addProp)
|
||||
confirmAddCustomNode(prop) {
|
||||
const p = prop || this.addProp
|
||||
this.customProps.push(p)
|
||||
this.addProp = {}
|
||||
this.customing = false
|
||||
},
|
||||
@@ -309,7 +319,7 @@ export default {
|
||||
}
|
||||
},
|
||||
_joinName(){
|
||||
return `feild_${this.deep}_${this.countAdd++}`
|
||||
return `field_${this.deep}_${this.countAdd++}`
|
||||
},
|
||||
onSetting(){
|
||||
this.modalVisible = true
|
||||
@@ -317,6 +327,7 @@ export default {
|
||||
for(const k in this.advancedValue) {
|
||||
if(this.pickValue[k]) this.advancedValue[k] = this.pickValue[k]
|
||||
}
|
||||
this.parseCustomProps()
|
||||
},
|
||||
|
||||
handleOk(){
|
||||
|
||||
@@ -7,6 +7,10 @@ module.exports = {
|
||||
template: 'public/index.html',
|
||||
filename: 'index.html'
|
||||
}
|
||||
},
|
||||
devServer: {
|
||||
// development server port 8000
|
||||
port: 8080
|
||||
}
|
||||
// css: {
|
||||
// loaderOptions: {
|
||||
|
||||
Reference in New Issue
Block a user