vue3集成jsoneditor的方法詳解
一、背景
之前在做錄制回放平臺的時候,需要前端展示子調(diào)用信息,子調(diào)用是一個請求列表數(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 感謝這位老哥的方案,我看了下源碼,沒有滿足我的需要,核心就是屬性需要自己加,因此我拿著他的代碼改了下
三、代碼實現(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)對應(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(() => { //這個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)文章
Vue3 computed初始化獲取設(shè)置值實現(xiàn)示例
這篇文章主要為大家介紹了Vue3 computed初始化以及獲取值設(shè)置值實現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10Vue 集成 PDF.js 實現(xiàn) PDF 預(yù)覽和添加水印的步驟
這篇文章主要介紹了如何在 Vue 中集成 Mozilla/PDF.js ,實現(xiàn)自定義的 PDF 預(yù)覽器,以及給被預(yù)覽的 PDF 添加水印2021-01-01vue使用axios實現(xiàn)文件上傳進(jìn)度的實時更新詳解
最近在學(xué)習(xí)axios,然后項目就用到了,所以這篇文章主要給大家介紹了關(guān)于vue中利用axios實現(xiàn)文件上傳進(jìn)度的實時更新的相關(guān)資料,文中先對axios進(jìn)行了簡單的介紹,方法大家理解學(xué)習(xí),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2017-12-12ant design vue嵌套表格及表格內(nèi)部編輯的用法說明
這篇文章主要介紹了ant design vue嵌套表格及表格內(nèi)部編輯的用法說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-10-10