【功能新增】基于 https://github.com/josdejong/jsoneditor 二次封装 JsonEditor 组件,提供 JSON 编辑器功能
This commit is contained in:
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
|
||||
}
|
||||
Reference in New Issue
Block a user