vue3集成jsoneditor的方法详解
作者:修烛老司机
JSONEditor是一个基于Web的工具,用于查看、编辑、格式化和验证JSON,它有各种模式,这篇文章主要为大家介绍了vue3集成jsoneditor的教程,希望对大家有所帮助
一、背景
之前在做录制回放平台的时候,需要前端展示子调用信息,子调用是一个请求列表数组结构,jsoneditor对数组的默认展示结构是[0].[1].[2]..的方式,为了达到如下的效果,必须用到 onNodeName的钩子函数,因此深入调研了下vue3如何集成jsoneditor
最后做出来的效果图
onNodeName的参考文档 github.com/josdejong/jsoneditor/blob/master/docs/api.md
二、参考方案
json-editor-vue3 感谢这位老哥的方案,我看了下源码,没有满足我的需要,核心就是属性需要自己加,因此我拿着他的代码改了下
三、代码实现
安装依赖 jsoneditor
npm install --save jsoneditor
jsoneditor是个开源的js的组件,参考文档 github.com/josdejong/jsoneditor
编写组件
目录结构如下
vue3-json-editor.tsx: 其中options的定义是完全参考jsoneditor的api文档的,具体需要什么功能,自己去实现对应的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的方法详解的详细内容,更多关于vue3集成jsoneditor的资料请关注脚本之家其它相关文章!