文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

基于Jsoneditor二次封装一个可实时预览的Json编辑器组件(React版)

2024-11-30 16:28

关注

你将学到:

设计思路

在介绍组件设计思路之前,有必要介绍一下著名的SOLID原则.

SOLID(单一功能、开闭原则、里氏替换、接口隔离以及依赖反转)是由罗伯特·C·马丁提出的面向对象编程和面向对象设计的五个基本原则。利用这些原则,程序员能更容易和高效的开发一个可维护和扩展的系统。 SOLID被典型的应用在测试驱动开发上,并且是敏捷开发以及自适应软件开发的基本原则的重要组成部分。

掌握好这5个原则将有利于我们开发出更优秀的组件,请默默记住.接下来我们来看看json编辑器的设计思路.

如上所示, 和任何一个输入框一样, 参考antd组件设计方式并兼容antd的form表单, 我们提供了onChange方法.(具体细节下文会详细介绍)

首先利用jsoneditor渲染的基本样式以及API,我们能实现一个基本可用的json编辑器,然后通过对外暴露的json和onChange属性进行数据双向绑定, 通过onError来监控异常或者输入的错误, 通过themeBgColor来修改默认的主题色,通过这几个接口,我们便能完全掌握一个组件的运行情况.

正文

接下来我们就正式开始我们的正文.由于本文的组件是基于react实现的,但是用在vue,angular上,基本模式同样适用.关键就是掌握好不同框架的生命周期.

在学习实现json编辑器组件之前,我们有必要了解一下jsoneditor这个第三方组件的用法与api.

1. jsoneditor的使用

我们先执行npm install安装我们的组件

npm install jsoneditor

其次手动引入样式文件

<link href="jsoneditor/dist/jsoneditor.min.css" rel="stylesheet" type="text/css">

这样,我们就能使用它的api了:

<div id="jsoneditor" style="width: 400px; height: 400px;">div>
<script>
// 创建编辑器
var container = document.getElementById("jsoneditor");
var editor = new JSONEditor(container);

// 设置json数据
function setJSON () {
var json = {
"Array": [1, 2, 3],
"Boolean": true,
"Null": null,
"Number": 123,
"Object": {"a": "b", "c": "d"},
"String": "Hello World"
};
editor.set(json);
}

// 获取json数据
function getJSON() {
var json = editor.get();
alert(JSON.stringify(json, null, 2));
}
script>

所以你可能看到如下界面:

为了能实现实时预览和编辑,光这样还远远不够,我们还需要进行额外的处理.我们需要用到jsoneditor其他的api和技巧.

2. 结合react进行二次封装

基于以上谈论,我们很容易将编辑器封装成react组件, 我们只需要在componentDidMount生命周期里初始化实例即可.react代码可能是这样的:

import React, { PureComponent } from 'react'
import JSONEditor from 'jsoneditor'

import 'jsoneditor/dist/jsoneditor.css'

class JsonEditor extends PureComponent {
initJsonEditor = () => {
const options = {
mode: 'code',
history: true,
onChange: this.onChange,
onValidationError: this.onError
};

this.jsoneditor = new JSONEditor(this.container, options)
this.jsoneditor.set(this.props.value)
}

componentDidMount () {
this.initJsonEditor()
}

componentWillUnmount () {
if (this.jsoneditor) {
this.jsoneditor.destroy()
}
}

render() {
return <div className="jsoneditor-react-container" ref={elem => this.container = elem} />
}
}
export default JsonEditor

至于options里的选项, 我们可以参考jsoneditor的API文档,里面写的很详细, 通过以上代码,我们便可以实现一个基本的react版的json编辑器组件.接下来我们来按照设计思路一步步实现可实时预览的json编辑器组件.

3. 实现预览和编辑视图

其实这一点很好实现,我们只需要实例化2个编辑器实例,一个用于预览,一个用于编辑就好了.

import React, { PureComponent } from 'react'
import JSONEditor from 'jsoneditor'
import 'jsoneditor/dist/jsoneditor.css'

class JsonEditor extends PureComponent {
onChange = () => {
let value = this.jsoneditor.get()
this.viewJsoneditor.set(value)
}

initJsonEditor = () => {
const options = {
mode: 'code',
history: true
};

this.jsoneditor = new JSONEditor(this.container, options)
this.jsoneditor.set(this.props.value)
}

initViewJsonEditor = () => {
const options = {
mode: 'view'
};

this.viewJsoneditor = new JSONEditor(this.viewContainer, options)
this.viewJsoneditor.set(this.props.value)
}

componentDidMount () {
this.initJsonEditor()
this.initViewJsonEditor()
}

componentDidUpdate() {
if(this.jsoneditor) {
this.jsoneditor.update(this.props.value)
this.viewJsoneditor.update(this.props.value)
}
}

render() {
return (
<div className="jsonEditWrap">
<div className="jsoneditor-react-container" ref={elem => this.container = elem} />
<div className="jsoneditor-react-container" ref={elem => this.viewContainer = elem} />
div>
);
}
}

export default JsonEditor

这样,我们便能实现一个初步的可实时预览的编辑器.可能效果长这样:

接近于成熟版,但是还有很多细节要处理.

4. 对外暴露属性和方法以支持不同场景的需要

import React, { PureComponent } from 'react'
import JSONEditor from 'jsoneditor'

import 'jsoneditor/dist/jsoneditor.css'

class JsonEditor extends PureComponent {
// 监听输入值的变化
onChange = () => {
let value = this.jsoneditor.get()
this.props.onChange && this.props.onChange(value)
this.viewJsoneditor.set(value)
}
// 对外暴露获取编辑器的json数据
getJson = () => {
this.props.getJson && this.props.getJson(this.jsoneditor.get())
}
// 对外提交错误信息
onError = (errArr) => {
this.props.onError && this.props.onError(errArr)
}

initJsonEditor = () => {
const options = {
mode: 'code',
history: true,
onChange: this.onChange,
onValidationError: this.onError
};

this.jsoneditor = new JSONEditor(this.container, options)
this.jsoneditor.set(this.props.value)
}

initViewJsonEditor = () => {
const options = {
mode: 'view'
};

this.viewJsoneditor = new JSONEditor(this.viewContainer, options)
this.viewJsoneditor.set(this.props.value)
}

componentDidMount () {
this.initJsonEditor()
this.initViewJsonEditor()
// 设置主题色
this.container.querySelector('.jsoneditor-menu').style.backgroundColor = this.props.themeBgColor
this.container.querySelector('.jsoneditor').style.border = `thin solid ${this.props.themeBgColor}`
this.viewContainer.querySelector('.jsoneditor-menu').style.backgroundColor = this.props.themeBgColor
this.viewContainer.querySelector('.jsoneditor').style.border = `thin solid ${this.props.themeBgColor}`
}

componentDidUpdate() {
if(this.jsoneditor) {
this.jsoneditor.update(this.props.value)
this.viewJsoneditor.update(this.props.value)
}
}

render() {
return (
<div className="jsonEditWrap">
<div className="jsoneditor-react-container" ref={elem => this.container = elem} />
<div className="jsoneditor-react-container" ref={elem => this.viewContainer = elem} />
div>
);
}
}

export default JsonEditor

通过以上的过程,我们已经完成一大半工作了,剩下的细节和优化工作,比如组件卸载时如何卸载实例, 对组件进行类型检测等,我们继续完成以上问题.

5. 使用PropTypes进行类型检测以及在组件卸载时清除实例

类型检测时react内部支持的,安装react的时候会自动帮我们安装PropTypes,具体用法可参考官网地址propTypes文档,其次我们会在react的componentWillUnmount生命周期中清除编辑器的实例以释放内存.完整代码如下:

import React, { PureComponent } from 'react'
import JSONEditor from 'jsoneditor'
import PropTypes from 'prop-types'
import 'jsoneditor/dist/jsoneditor.css'


class JsonEditor extends PureComponent {
onChange = () => {
let value = this.jsoneditor.get()
this.props.onChange && this.props.onChange(value)
this.viewJsoneditor.set(value)
}

getJson = () => {
this.props.getJson && this.props.getJson(this.jsoneditor.get())
}

onError = (errArr) => {
this.props.onError && this.props.onError(errArr)
}

initJsonEditor = () => {
const options = {
mode: 'code',
history: true,
onChange: this.onChange,
onValidationError: this.onError
};

this.jsoneditor = new JSONEditor(this.container, options)
this.jsoneditor.set(this.props.value)
}

initViewJsonEditor = () => {
const options = {
mode: 'view'
};

this.viewJsoneditor = new JSONEditor(this.viewContainer, options)
this.viewJsoneditor.set(this.props.value)
}

componentDidMount () {
this.initJsonEditor()
this.initViewJsonEditor()
// 设置主题色
this.container.querySelector('.jsoneditor-menu').style.backgroundColor = this.props.themeBgColor
this.container.querySelector('.jsoneditor').style.border = `thin solid ${this.props.themeBgColor}`
this.viewContainer.querySelector('.jsoneditor-menu').style.backgroundColor = this.props.themeBgColor
this.viewContainer.querySelector('.jsoneditor').style.border = `thin solid ${this.props.themeBgColor}`
}

componentWillUnmount () {
if (this.jsoneditor) {
this.jsoneditor.destroy()
this.viewJsoneditor.destroy()
}
}

componentDidUpdate() {
if(this.jsoneditor) {
this.jsoneditor.update(this.props.value)
this.viewJsoneditor.update(this.props.value)
}
}

render() {
return (
<div className="jsonEditWrap">
<div className="jsoneditor-react-container" ref={elem => this.container = elem} />
<div className="jsoneditor-react-container" ref={elem => this.viewContainer = elem} />
div>
);
}
}

JsonEditor.propTypes = {
json: PropTypes.object,
onChange: PropTypes.func,
getJson: PropTypes.func,
onError: PropTypes.func,
themeBgColor: PropTypes.string
}

export default JsonEditor

由于组件严格遵守开闭原则,所以我们可以提供更加定制的功能在我们的json编辑器中,已实现不同项目的需求.对于组件开发的健壮性探讨,除了使用propTypes外还可以基于typescript开发,这样适合团队开发组件库或者复杂项目组件的追溯和查错.

来源:趣谈前端内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯