vue3集成jsoneditor的方法詳解
一、背景
之前在做錄制回放平臺的時(shí)候,需要前端展示子調(diào)用信息,子調(diào)用是一個(gè)請求列表數(shù)組結(jié)構(gòu),jsoneditor對數(shù)組的默認(rèn)展示結(jié)構(gòu)是[0].[1].[2]..的方式,為了達(dá)到如下的效果,必須用到 onNodeName的鉤子函數(shù),因此深入調(diào)研了下vue3如何集成jsoneditor
最后做出來的效果圖

onNodeName的參考文檔 github.com/josdejong/jsoneditor/blob/master/docs/api.md

二、參考方案
json-editor-vue3 感謝這位老哥的方案,我看了下源碼,沒有滿足我的需要,核心就是屬性需要自己加,因此我拿著他的代碼改了下
三、代碼實(shí)現(xiàn)
安裝依賴 jsoneditor
npm install --save jsoneditor
jsoneditor是個(gè)開源的js的組件,參考文檔 github.com/josdejong/jsoneditor
編寫組件
目錄結(jié)構(gòu)如下

vue3-json-editor.tsx: 其中options的定義是完全參考jsoneditor的api文檔的,具體需要什么功能,自己去實(shí)現(xiàn)對應(yīng)的options即可!
import { ComponentPublicInstance, defineComponent, getCurrentInstance, onMounted, reactive, watch } from 'vue'
// @ts-ignore
// eslint-disable-next-line import/extensions
import JsonEditor from 'jsoneditor';
import 'jsoneditor/dist/jsoneditor.min.css';
// eslint-disable-next-line import/prefer-default-export
export const Vue3JsonEditor = defineComponent({
props: {
modelValue: [String, Boolean, Object, Array],
showBtns: [Boolean],
expandedOnStart: {
type: Boolean,
default: false
},
navigationBar: {
type: Boolean,
default: true
},
mode: {
type: String,
default: 'tree'
},
modes: {
type: Array,
default () {
return ['tree', 'code', 'form', 'text', 'view']
}
},
lang: {
type: String,
default: 'en'
},
onNodeName: {
type: Function,
default: ()=>{}
}
},
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'],
uid: `jsoneditor-vue-${getCurrentInstance()?.uid}`
})
watch(
() => props.modelValue as unknown as any,
async (val) => {
if (!state.internalChange) {
state.json = val
// eslint-disable-next-line no-use-before-define
await setEditor(val)
state.error = false
// eslint-disable-next-line no-use-before-define
expandAll()
}
}, { immediate: true })
onMounted(() => {
//這個(gè)options的定義是完全參考jsoneditor的api文檔的
const options = {
mode: props.mode,
modes: props.modes,
onChange () {
try {
const json = state.editor.get()
state.json = json
state.error = false
// eslint-disable-next-line vue/custom-event-name-casing
emit('json-change', json)
state.internalChange = true
emit('input', json)
root.$nextTick(function () {
state.internalChange = false
})
} catch (e) {
state.error = true
// eslint-disable-next-line vue/custom-event-name-casing
emit('has-error', e)
}
},
onNodeName(v: object) {
// eslint-disable-next-line vue/custom-event-name-casing
return props.onNodeName(v);
},
onModeChange () {
// eslint-disable-next-line no-use-before-define
expandAll()
},
navigationBar: props.navigationBar
}
state.editor = new JsonEditor(
document.querySelector(`#${state.uid}`),
options,
state.json
)
// eslint-disable-next-line vue/custom-event-name-casing
emit('provide-editor', state.editor)
})
function expandAll () {
if (props.expandedOnStart && state.expandedModes.includes(props.mode)) {
(state.editor as any).expandAll()
}
}
function onSave () {
// eslint-disable-next-line vue/custom-event-name-casing
emit('json-save', state.json)
}
function setEditor (value: any): void {
if (state.editor) state.editor.set(value)
}
return () => {
// @ts-ignore
// @ts-ignore
return (
<div>
<div id={state.uid} class={'jsoneditor-vue'}></div>
</div>
)
}
}
})style.css
.ace_line_group {
text-align: left;
}
.json-editor-container {
display: flex;
width: 100%;
}
.json-editor-container .tree-mode {
width: 50%;
}
.json-editor-container .code-mode {
flex-grow: 1;
}
.jsoneditor-btns {
text-align: center;
margin-top: 10px;
}
.jsoneditor-vue .jsoneditor-outer {
min-height: 150px;
}
.jsoneditor-vue div.jsoneditor-tree {
min-height: 350px;
}
.json-save-btn {
background-color: #20a0ff;
border: none;
color: #fff;
padding: 5px 10px;
border-radius: 5px;
cursor: pointer;
}
.json-save-btn:focus {
outline: none;
}
.json-save-btn[disabled] {
background-color: #1d8ce0;
cursor: not-allowed;
}
code {
background-color: #f5f5f5;
}index.ts
export * from './vue3-json-editor';
四、如何使用
<template>
<div class="container">
<Vue3JsonEditor
v-model="json"
mode='view'
:show-btns="true"
:on-node-name="onNodeName"
/>
</div>
</template>
<script lang="ts" setup>
import {computed,} from 'vue'
import {Vue3JsonEditor} from "@/components/json-editor";
const props = defineProps({
record: {
type: Object,
default() {
return {
request: undefined,
};
},
},
});
const json=computed(()=>{
const {record} = props;
return record.subInvocations;
});
// eslint-disable-next-line consistent-return
const onNodeName = (node: {
value: any; type: any
})=>{
if (node.type==='object' && node.value.identity) {
return node.value.identity;
}
return undefined;
}
</script>
<script lang="ts">
export default {
name: 'Invocations',
};
</script>
<style scoped lang="less">
.container {
padding: 0 20px 20px 20px;
}
</style>以上就是vue3集成jsoneditor的方法詳解的詳細(xì)內(nèi)容,更多關(guān)于vue3集成jsoneditor的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
vue-print-nb實(shí)現(xiàn)頁面打印功能實(shí)例(含分頁打印)
在項(xiàng)目中,有時(shí)需要打印頁面的表格,在網(wǎng)上找了一個(gè)打印組件vue-print-nb,用了還不錯,所以下面這篇文章主要給大家介紹了關(guān)于vue-print-nb實(shí)現(xiàn)頁面打印功能的相關(guān)資料,需要的朋友可以參考下2022-08-08
Vue-cli框架實(shí)現(xiàn)計(jì)時(shí)器應(yīng)用
這篇文章主要為大家詳細(xì)介紹了Vue-cli框架實(shí)現(xiàn)計(jì)時(shí)器應(yīng)用,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08
vue2.0 如何把子組件的數(shù)據(jù)傳給父組件(推薦)
這篇文章主要介紹了vue2.0 如何把子組件的數(shù)據(jù)傳給父組件,需要的朋友可以參考下2018-01-01
vue.js異步上傳文件前后端實(shí)現(xiàn)代碼
這篇文章主要為大家詳細(xì)介紹了vue.js異步上傳文件前后端的實(shí)現(xiàn)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08
Element Plus 表格中的復(fù)制功能使用實(shí)戰(zhàn)指南
本文介紹了ElementPlus表格的cell-dblclick事件的使用方法,總結(jié)了當(dāng)前項(xiàng)目的優(yōu)勢,如兼容性好、特殊列處理、用戶反饋和錯誤處理等,感興趣的朋友跟隨小編一起看看吧2026-02-02
vue修改數(shù)據(jù)視圖更新原理學(xué)習(xí)
這篇文章主要為大家介紹了vue修改數(shù)據(jù)視圖更新原理學(xué)習(xí),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11
Vue3+TypeScript項(xiàng)目中安裝PDF.js詳細(xì)的步驟
這篇文章主要介紹了Vue3+TypeScript項(xiàng)目中安裝PDF.js詳細(xì)的步驟,通過示例代碼詳細(xì)介紹了包括安裝步驟、基礎(chǔ)使用示例、創(chuàng)建可復(fù)用PDF查看器組件、注意事項(xiàng)等,需要的朋友可以參考下2026-01-01

