-
-
Notifications
You must be signed in to change notification settings - Fork 28
/
vue3-json-editor.tsx
131 lines (122 loc) · 3.13 KB
/
vue3-json-editor.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
import { ComponentPublicInstance, defineComponent, getCurrentInstance, onMounted, reactive, watch } from 'vue'
import JsonEditor from './assets/jsoneditor'
import './assets/jsoneditor.css'
import './style.css'
export const Vue3JsonEditor = defineComponent({
props: {
modelValue: [String, Boolean, Object, Array],
showBtns: [Boolean],
expandedOnStart: {
type: Boolean,
default: false
},
mode: {
type: String,
default: 'tree'
},
modes: {
type: Array,
default: function () {
return ['tree', 'code', 'form', 'text', 'view']
}
},
lang: {
type: String,
default: 'en'
}
},
setup (props: any, { emit }) {
const root = getCurrentInstance()?.root.proxy as ComponentPublicInstance
const state = reactive({
editor: null as any,
error: false,
json: {},
internalChange: false,
expandedModes: ['tree', 'view', 'form'],
locale: {
it: {
save: 'SALVA'
},
en: {
save: 'SAVE'
},
zh: {
save: '保存'
}
},
uid: `jsoneditor-vue-${getCurrentInstance()?.uid}`
})
watch(
() => props.modelValue as unknown as any,
async (val) => {
if (!state.internalChange) {
state.json = val
await setEditor(val)
state.error = false
expandAll()
}
}, { immediate: true })
onMounted(() => {
const options = {
mode: props.mode,
modes: props.modes,
onChange () {
try {
const json = state.editor.get()
state.json = json
state.error = false
emit('json-change', json)
state.internalChange = true
emit('input', json)
root.$nextTick(function () {
state.internalChange = false
})
} catch (e) {
state.error = true
emit('has-error', e)
}
},
onModeChange (mode) {
emit('mode-change', mode)
state.expandedModes.includes(mode) && expandAll()
}
}
state.editor = new JsonEditor(
document.querySelector(`#${state.uid}`),
options,
state.json
)
emit('provide-editor', state.editor)
})
function expandAll () {
if (props.expandedOnStart && state.expandedModes.includes(props.mode)) {
(state.editor as any).expandAll()
}
}
function onSave () {
emit('json-save', state.json)
}
function setEditor (value: any): void {
if (state.editor) state.editor.set(value)
}
return () => {
return (
<div>
<div id={state.uid} class={'jsoneditor-vue'}></div>
{props.showBtns !== false && (
<div class={'jsoneditor-btns'}>
<button
class={'json-save-btn'}
type={'button'}
onClick={() => {
onSave()
}}
disabled={state.error}
>{state.locale[props.lang].save}</button>
</div>
)}
</div>
)
}
}
})