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

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

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

vue3-json-editor.tsx: 其中options的定義是完全參考jsoneditor的api文檔的,具體需要什么功能,自己去實現(xiàn)對應的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(() => {
//這個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的方法詳解的詳細內(nèi)容,更多關(guān)于vue3集成jsoneditor的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Vue3 computed初始化獲取設(shè)置值實現(xiàn)示例
這篇文章主要為大家介紹了Vue3 computed初始化以及獲取值設(shè)置值實現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-10-10
Vue 集成 PDF.js 實現(xiàn) PDF 預覽和添加水印的步驟
這篇文章主要介紹了如何在 Vue 中集成 Mozilla/PDF.js ,實現(xiàn)自定義的 PDF 預覽器,以及給被預覽的 PDF 添加水印2021-01-01
vue使用axios實現(xiàn)文件上傳進度的實時更新詳解
最近在學習axios,然后項目就用到了,所以這篇文章主要給大家介紹了關(guān)于vue中利用axios實現(xiàn)文件上傳進度的實時更新的相關(guān)資料,文中先對axios進行了簡單的介紹,方法大家理解學習,需要的朋友們下面隨著小編來一起學習學習吧。2017-12-12
ant design vue嵌套表格及表格內(nèi)部編輯的用法說明
這篇文章主要介紹了ant design vue嵌套表格及表格內(nèi)部編輯的用法說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-10-10

