【功能新增】基于 https://github.com/josdejong/jsoneditor 二次封装 JsonEditor 组件,提供 JSON 编辑器功能
This commit is contained in:
parent
7cb4c48d47
commit
6265d6d923
@ -51,6 +51,7 @@
|
||||
"fast-xml-parser": "^4.3.2",
|
||||
"highlight.js": "^11.9.0",
|
||||
"jsencrypt": "^3.3.2",
|
||||
"jsoneditor": "^10.1.3",
|
||||
"lodash-es": "^4.17.21",
|
||||
"markdown-it": "^14.1.0",
|
||||
"markmap-common": "^0.16.0",
|
||||
@ -67,7 +68,6 @@
|
||||
"sortablejs": "^1.15.3",
|
||||
"steady-xml": "^0.1.0",
|
||||
"url": "^0.11.3",
|
||||
"v3-jsoneditor": "^0.0.6",
|
||||
"video.js": "^7.21.5",
|
||||
"vue": "3.5.12",
|
||||
"vue-dompurify-html": "^4.1.4",
|
||||
@ -85,6 +85,7 @@
|
||||
"@iconify/json": "^2.2.187",
|
||||
"@intlify/unplugin-vue-i18n": "^2.0.0",
|
||||
"@purge-icons/generated": "^0.9.0",
|
||||
"@types/jsoneditor": "^9.9.5",
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"@types/node": "^20.11.21",
|
||||
"@types/nprogress": "^0.2.3",
|
||||
|
@ -86,6 +86,9 @@ importers:
|
||||
jsencrypt:
|
||||
specifier: ^3.3.2
|
||||
version: 3.3.2
|
||||
jsoneditor:
|
||||
specifier: ^10.1.3
|
||||
version: 10.1.3
|
||||
lodash-es:
|
||||
specifier: ^4.17.21
|
||||
version: 4.17.21
|
||||
@ -134,9 +137,6 @@ importers:
|
||||
url:
|
||||
specifier: ^0.11.3
|
||||
version: 0.11.4
|
||||
v3-jsoneditor:
|
||||
specifier: ^0.0.6
|
||||
version: 0.0.6
|
||||
video.js:
|
||||
specifier: ^7.21.5
|
||||
version: 7.21.6
|
||||
@ -183,6 +183,9 @@ importers:
|
||||
'@purge-icons/generated':
|
||||
specifier: ^0.9.0
|
||||
version: 0.9.0
|
||||
'@types/jsoneditor':
|
||||
specifier: ^9.9.5
|
||||
version: 9.9.5
|
||||
'@types/lodash-es':
|
||||
specifier: ^4.17.12
|
||||
version: 4.17.12
|
||||
@ -1693,6 +1696,9 @@ packages:
|
||||
resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==}
|
||||
engines: {node: '>=10.13.0'}
|
||||
|
||||
'@types/ace@0.0.52':
|
||||
resolution: {integrity: sha512-YPF9S7fzpuyrxru+sG/rrTpZkC6gpHBPF14W3x70kqVOD+ks6jkYLapk4yceh36xej7K4HYxcyz9ZDQ2lTvwgQ==}
|
||||
|
||||
'@types/conventional-commits-parser@5.0.1':
|
||||
resolution: {integrity: sha512-7uz5EHdzz2TqoMfV7ee61Egf5y6NkcO4FB/1iCCQnbeiI1F3xzv3vK5dBCXUCLQgGYS+mUeigK1iKQzvED+QnQ==}
|
||||
|
||||
@ -1804,6 +1810,9 @@ packages:
|
||||
'@types/json-schema@7.0.15':
|
||||
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
|
||||
|
||||
'@types/jsoneditor@9.9.5':
|
||||
resolution: {integrity: sha512-+Wex7QCirPcG90WA8/CmvDO21KUjz63/G7Yk52Yx/NhWHw5DyeET/L+wjZHAeNeNCCnMOTEtVX5gc3F4UXwXMQ==}
|
||||
|
||||
'@types/lodash-es@4.17.12':
|
||||
resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==}
|
||||
|
||||
@ -2336,8 +2345,8 @@ packages:
|
||||
resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==}
|
||||
hasBin: true
|
||||
|
||||
ace-builds@1.39.0:
|
||||
resolution: {integrity: sha512-MqoZojv4gpc5QyTMor/dS6kmruDV9db9LVZbCiT4qYz6WsDiv4qyG5f7ZPc+wjUl6oLMqgCAsBjo1whdSVyMlQ==}
|
||||
ace-builds@1.39.1:
|
||||
resolution: {integrity: sha512-HcJbBzx8qY66t9gZo/sQu7pi0wO/CFLdYn1LxQO1WQTfIkMfyc7LRnBpsp/oNCSSU/LL83jXHN1fqyOTuIhUjg==}
|
||||
|
||||
acorn-jsx@5.3.2:
|
||||
resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
|
||||
@ -4069,8 +4078,8 @@ packages:
|
||||
resolution: {integrity: sha512-WYDyuc/uFcGp6YtM2H0uKmUwieOuzeE/5YocFJLnLfclZ4inf3mRn8ZVy1s7Hxji7Jxm6Ss8gqpexD/GlKoGgg==}
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
|
||||
jsoneditor@9.10.5:
|
||||
resolution: {integrity: sha512-fVZ0NMt+zm4rqTKBv2x7zPdLeaRyKo1EjJkaR1QjK4gEM1rMwICILYSW1OPxSc1qqyAoDaA/eeNrluKoxOocCA==}
|
||||
jsoneditor@10.1.3:
|
||||
resolution: {integrity: sha512-zvbkiduFR19vLMJN1sSvBs9baGDdQRJGmKy6+/vQzDFhx//oEd6WAkrmmTeU4NNk9MAo+ZirENuwbtJXvS9M5g==}
|
||||
|
||||
jsonfile@6.1.0:
|
||||
resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==}
|
||||
@ -4079,8 +4088,8 @@ packages:
|
||||
resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==}
|
||||
engines: {'0': node >= 0.2.0}
|
||||
|
||||
jsonrepair@3.1.0:
|
||||
resolution: {integrity: sha512-idqReg23J0PVRAADmZMc5xQM3xeOX5bTB6OTyMnzq33IXJXmn9iJuWIEvGmrN80rQf4d7uLTMEDwpzujNcI0Rg==}
|
||||
jsonrepair@3.12.0:
|
||||
resolution: {integrity: sha512-SWfjz8SuQ0wZjwsxtSJ3Zy8vvLg6aO/kxcp9TWNPGwJKgTZVfhNEQBMk/vPOpYCDFWRxD6QWuI6IHR1t615f0w==}
|
||||
hasBin: true
|
||||
|
||||
katex@0.16.11:
|
||||
@ -4402,9 +4411,6 @@ packages:
|
||||
mlly@1.7.3:
|
||||
resolution: {integrity: sha512-xUsx5n/mN0uQf4V548PKQ+YShA4/IW0KI1dZhrNrPCLG+xizETbHTkOa1f8/xut9JRPp8kQuMnz0oqwkTiLo/A==}
|
||||
|
||||
mobius1-selectr@2.4.13:
|
||||
resolution: {integrity: sha512-Mk9qDrvU44UUL0EBhbAA1phfQZ7aMZPjwtL7wkpiBzGh8dETGqfsh50mWoX9EkjDlkONlErWXArHCKfoxVg0Bw==}
|
||||
|
||||
moddle-xml@10.1.0:
|
||||
resolution: {integrity: sha512-erWckwLt+dYskewKXJso9u+aAZ5172lOiYxSOqKCPTy7L/xmqH1PoeoA7eVC7oJTt3PqF5TkZzUmbjGH6soQBg==}
|
||||
|
||||
@ -5561,9 +5567,6 @@ packages:
|
||||
resolution: {integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==}
|
||||
hasBin: true
|
||||
|
||||
v3-jsoneditor@0.0.6:
|
||||
resolution: {integrity: sha512-9G0sXWXUn67SBkn46ycWfwPwjuJu/lcsQaNzMtXAR2/95hMV21WfcRNsqJ+vVVrSHQehohB/9fVLwYEXz0u/KA==}
|
||||
|
||||
vanilla-picker@2.12.3:
|
||||
resolution: {integrity: sha512-qVkT1E7yMbUsB2mmJNFmaXMWE2hF8ffqzMMwe9zdAikd8u2VfnsVY2HQcOUi2F38bgbxzlJBEdS1UUhOXdF9GQ==}
|
||||
|
||||
@ -7334,6 +7337,8 @@ snapshots:
|
||||
|
||||
'@trysound/sax@0.2.0': {}
|
||||
|
||||
'@types/ace@0.0.52': {}
|
||||
|
||||
'@types/conventional-commits-parser@5.0.1':
|
||||
dependencies:
|
||||
'@types/node': 20.17.9
|
||||
@ -7468,6 +7473,11 @@ snapshots:
|
||||
|
||||
'@types/json-schema@7.0.15': {}
|
||||
|
||||
'@types/jsoneditor@9.9.5':
|
||||
dependencies:
|
||||
'@types/ace': 0.0.52
|
||||
ajv: 6.12.6
|
||||
|
||||
'@types/lodash-es@4.17.12':
|
||||
dependencies:
|
||||
'@types/lodash': 4.17.13
|
||||
@ -7830,7 +7840,7 @@ snapshots:
|
||||
'@unocss/rule-utils@0.58.9':
|
||||
dependencies:
|
||||
'@unocss/core': 0.58.9
|
||||
magic-string: 0.30.14
|
||||
magic-string: 0.30.17
|
||||
|
||||
'@unocss/rule-utils@66.1.0-beta.5':
|
||||
dependencies:
|
||||
@ -8272,7 +8282,7 @@ snapshots:
|
||||
jsonparse: 1.3.1
|
||||
through: 2.3.8
|
||||
|
||||
ace-builds@1.39.0: {}
|
||||
ace-builds@1.39.1: {}
|
||||
|
||||
acorn-jsx@5.3.2(acorn@8.14.0):
|
||||
dependencies:
|
||||
@ -10179,15 +10189,14 @@ snapshots:
|
||||
espree: 9.6.1
|
||||
semver: 7.6.3
|
||||
|
||||
jsoneditor@9.10.5:
|
||||
jsoneditor@10.1.3:
|
||||
dependencies:
|
||||
ace-builds: 1.39.0
|
||||
ace-builds: 1.39.1
|
||||
ajv: 6.12.6
|
||||
javascript-natural-sort: 0.7.1
|
||||
jmespath: 0.16.0
|
||||
json-source-map: 0.6.1
|
||||
jsonrepair: 3.1.0
|
||||
mobius1-selectr: 2.4.13
|
||||
jsonrepair: 3.12.0
|
||||
picomodal: 3.0.0
|
||||
vanilla-picker: 2.12.3
|
||||
|
||||
@ -10199,7 +10208,7 @@ snapshots:
|
||||
|
||||
jsonparse@1.3.1: {}
|
||||
|
||||
jsonrepair@3.1.0: {}
|
||||
jsonrepair@3.12.0: {}
|
||||
|
||||
katex@0.16.11:
|
||||
dependencies:
|
||||
@ -10550,8 +10559,6 @@ snapshots:
|
||||
pkg-types: 1.2.1
|
||||
ufo: 1.5.4
|
||||
|
||||
mobius1-selectr@2.4.13: {}
|
||||
|
||||
moddle-xml@10.1.0:
|
||||
dependencies:
|
||||
min-dash: 4.2.2
|
||||
@ -11811,10 +11818,6 @@ snapshots:
|
||||
|
||||
uuid@10.0.0: {}
|
||||
|
||||
v3-jsoneditor@0.0.6:
|
||||
dependencies:
|
||||
jsoneditor: 9.10.5
|
||||
|
||||
vanilla-picker@2.12.3:
|
||||
dependencies:
|
||||
'@sphinxxxx/color-conversion': 2.2.2
|
||||
|
3
src/components/JsonEditor/index.ts
Normal file
3
src/components/JsonEditor/index.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import JsonEditor from './src/JsonEditor.vue'
|
||||
|
||||
export { JsonEditor }
|
109
src/components/JsonEditor/src/JsonEditor.vue
Normal file
109
src/components/JsonEditor/src/JsonEditor.vue
Normal file
@ -0,0 +1,109 @@
|
||||
<template>
|
||||
<div ref="jsonEditorContainer" class="json-editor" :style="{ height }"></div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { useVModel } from '@vueuse/core'
|
||||
import { onBeforeUnmount, onMounted, ref, watch } from 'vue'
|
||||
import JSONEditor, { JSONEditorMode, JSONEditorOptions } from 'jsoneditor'
|
||||
import 'jsoneditor/dist/jsoneditor.min.css'
|
||||
import { JsonEditorEmits, JsonEditorExpose, JsonEditorProps } from '../types'
|
||||
|
||||
/** 基于 https://github.com/josdejong/jsoneditor 二次封装组件,提供 JSON 编辑器功能。 */
|
||||
defineOptions({ name: 'JsonEditor' })
|
||||
|
||||
const props = withDefaults(defineProps<JsonEditorProps>(), {
|
||||
mode: 'tree' as JSONEditorMode,
|
||||
height: '400px',
|
||||
showModeSelection: false,
|
||||
showNavigationBar: false,
|
||||
showStatusBar: false,
|
||||
showMainMenuBar: true
|
||||
})
|
||||
|
||||
const emits = defineEmits<JsonEditorEmits>()
|
||||
const jsonObj = useVModel(props, 'modelValue', emits) as Ref<any>
|
||||
const jsonEditorContainer = ref<HTMLElement | null>(null)
|
||||
let jsonEditor: JSONEditor | null = null
|
||||
|
||||
// 设置默认值
|
||||
const height = props.height
|
||||
|
||||
// 初始化JSONEditor
|
||||
const initJsonEditor = () => {
|
||||
if (!jsonEditorContainer.value) return
|
||||
|
||||
// 合并默认配置和用户自定义配置
|
||||
const options: JSONEditorOptions = {
|
||||
mode: props.mode,
|
||||
modes: props.showModeSelection
|
||||
? (['tree', 'code', 'form', 'text', 'view', 'preview'] as JSONEditorMode[])
|
||||
: undefined,
|
||||
navigationBar: props.showNavigationBar,
|
||||
statusBar: props.showStatusBar,
|
||||
mainMenuBar: props.showMainMenuBar,
|
||||
onChangeJSON: (json: any) => {
|
||||
jsonObj.value = json
|
||||
emits('change', json)
|
||||
},
|
||||
onValidationError: (errors: any) => {
|
||||
emits('error', errors)
|
||||
},
|
||||
...props.options
|
||||
} as JSONEditorOptions
|
||||
|
||||
// 创建JSONEditor实例
|
||||
jsonEditor = new JSONEditor(jsonEditorContainer.value, options)
|
||||
|
||||
// 设置初始值
|
||||
if (jsonObj.value) {
|
||||
jsonEditor.set(jsonObj.value)
|
||||
}
|
||||
}
|
||||
|
||||
// 监听数据变化
|
||||
watch(
|
||||
() => jsonObj.value,
|
||||
(newValue) => {
|
||||
if (!jsonEditor) return
|
||||
|
||||
try {
|
||||
// 防止无限循环更新
|
||||
const currentJson = jsonEditor.get()
|
||||
if (JSON.stringify(currentJson) !== JSON.stringify(newValue)) {
|
||||
jsonEditor.update(newValue)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('JSON更新失败:', error)
|
||||
}
|
||||
},
|
||||
{ deep: true }
|
||||
)
|
||||
|
||||
// 生命周期钩子
|
||||
onMounted(() => {
|
||||
initJsonEditor()
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
if (jsonEditor) {
|
||||
jsonEditor.destroy()
|
||||
jsonEditor = null
|
||||
}
|
||||
})
|
||||
|
||||
// 暴露方法
|
||||
defineExpose<JsonEditorExpose>({
|
||||
// 获取编辑器实例,以便可以调用更多JSONEditor的原生方法
|
||||
getEditor: () => jsonEditor
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
/* 隐藏 Ace 编辑器的 powered by ace 标记 */
|
||||
:deep(.jsoneditor-menu) {
|
||||
/* 隐藏 powered by ace 标记 */
|
||||
.jsoneditor-poweredBy {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
</style>
|
80
src/components/JsonEditor/types/index.ts
Normal file
80
src/components/JsonEditor/types/index.ts
Normal file
@ -0,0 +1,80 @@
|
||||
import { JSONEditorOptions, JSONEditorMode } from 'jsoneditor'
|
||||
|
||||
export interface JsonEditorProps {
|
||||
/**
|
||||
* JSON数据,支持双向绑定
|
||||
*/
|
||||
modelValue: any
|
||||
|
||||
/**
|
||||
* 编辑器模式
|
||||
* @default 'tree'
|
||||
*/
|
||||
mode?: JSONEditorMode
|
||||
|
||||
/**
|
||||
* 编辑器高度
|
||||
* @default '400px'
|
||||
*/
|
||||
height?: string
|
||||
|
||||
/**
|
||||
* 是否显示模式选择下拉菜单
|
||||
* @default false
|
||||
*/
|
||||
showModeSelection?: boolean
|
||||
|
||||
/**
|
||||
* 是否显示导航栏
|
||||
* @default false
|
||||
*/
|
||||
showNavigationBar?: boolean
|
||||
|
||||
/**
|
||||
* 是否显示状态栏
|
||||
* @default true
|
||||
*/
|
||||
showStatusBar?: boolean
|
||||
|
||||
/**
|
||||
* 是否显示主菜单栏
|
||||
* @default true
|
||||
*/
|
||||
showMainMenuBar?: boolean
|
||||
|
||||
/**
|
||||
* JSONEditor配置选项
|
||||
* @see https://github.com/josdejong/jsoneditor/blob/develop/docs/api.md
|
||||
*/
|
||||
options?: Partial<JSONEditorOptions>
|
||||
}
|
||||
|
||||
/**
|
||||
* JsonEditor组件触发的事件
|
||||
*/
|
||||
export interface JsonEditorEmits {
|
||||
/**
|
||||
* 数据更新时触发
|
||||
*/
|
||||
(e: 'update:modelValue', value: any): void
|
||||
|
||||
/**
|
||||
* 数据变化时触发
|
||||
*/
|
||||
(e: 'change', value: any): void
|
||||
|
||||
/**
|
||||
* 验证错误时触发
|
||||
*/
|
||||
(e: 'error', errors: any): void
|
||||
}
|
||||
|
||||
/**
|
||||
* JsonEditor组件暴露的方法
|
||||
*/
|
||||
export interface JsonEditorExpose {
|
||||
/**
|
||||
* 获取原始的JSONEditor实例
|
||||
*/
|
||||
getEditor: () => any
|
||||
}
|
Loading…
Reference in New Issue
Block a user