vue3集成jsoneditor的方法详解

 更新时间:2023年09月07日 11:16:09   作者:修烛老司机  
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的资料请关注脚本之家其它相关文章!

相关文章

  • Vue使用Element-UI生成并展示表头序号的方法

    Vue使用Element-UI生成并展示表头序号的方法

    序号算是在展示数据的时候,一种很普遍的属性了,我们可以自己写生成序号的规则,也可以借助第三方,这篇文章主要介绍了Vue使用Element-UI生成并展示表头序号的方法,需要的朋友可以参考下
    2023-01-01
  • vue3+vite中使用import.meta.glob的操作代码

    vue3+vite中使用import.meta.glob的操作代码

    在vue2的时候,我们一般引入多个js或者其他文件,一般使用  require.context 来引入多个不同的文件,但是vite中是不支持 require的,他推出了一个功能用import.meta.glob来引入多个,单个的文件,下面通过本文介绍vue3+vite中使用import.meta.glob,需要的朋友可以参考下
    2022-11-11
  • vue作用域插槽详解、slot、v-slot、slot-scope

    vue作用域插槽详解、slot、v-slot、slot-scope

    这篇文章主要介绍了vue作用域插槽详解、slot、v-slot、slot-scope,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-03-03
  • vue v-for 使用问题整理小结

    vue v-for 使用问题整理小结

    使用v-for指令的时候遇到一个错误问题,具体错误代码在文章给大家列出,对vue v-for使用问题感兴趣的朋友跟随小编一起学习吧
    2019-08-08
  • vue中两种路由模式的实现详解

    vue中两种路由模式的实现详解

    这篇文章主要为大家详细介绍了vue中两种路由模式的实现,文中的示例代码讲解详细,具有一定的学习价值,感兴趣的小伙伴可以了解一下
    2023-08-08
  • Vue组件通信方法案例总结

    Vue组件通信方法案例总结

    这篇文章主要介绍了Vue组件通信方法案例总结,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-09-09
  • vue动态路由刷新失效以及404页面处理办法

    vue动态路由刷新失效以及404页面处理办法

    作为一个前端新手,项目中遇到权限处理时,通常会采用动态添加路由的方法来实现,下面这篇文章主要给大家介绍了关于vue动态路由刷新失效以及404页面处理办法的相关资料,需要的朋友可以参考下
    2023-11-11
  • vuex入门教程,图文+实例解析

    vuex入门教程,图文+实例解析

    这篇文章主要介绍了vuex入门教程,图文+实例解析,具有很好的参考价值,希望对大家有所帮助。
    2022-03-03
  • vue封装自定义指令之动态显示title操作(溢出显示,不溢出不显示)

    vue封装自定义指令之动态显示title操作(溢出显示,不溢出不显示)

    这篇文章主要介绍了vue封装自定义指令之动态显示title操作(溢出显示,不溢出不显示),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-11-11
  • VUE项目中引入JS文件的方法总结

    VUE项目中引入JS文件的方法总结

    在vue中如果把所有的代码都写到一个页面中,有时比较难找,显得比较复杂,下面这篇文章主要给大家介绍了关于VUE项目中引入JS文件的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-06-06

最新评论