持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第1天,点击查看活动详情
手把手跟着设计一个自定义json编辑器
设计一个实时编辑器思路
使用jsoneditor
本想借助网上资料自己从头撸一个json编辑器,但是奈何太菜,所以只有跟着改造一下json编辑器,首先借助一个基础的j son解析的编辑器json编辑器文档
按照文档先跑起来一个json基础编辑器
npm install jsoneditor
然后引用jsoneditor包中的js问价和css文件
<link href="jsoneditor/dist/jsoneditor.min.css" rel="stylesheet" type="text/css">
<script src="jsoneditor/dist/jsoneditor.min.js"></script>
然后就可以创建一个标签作为editor的容器
<div id="jsoneditor" style="width: 400px; height: 400px;"></div>
加载容器标签后,再使用javascript加载editor内容,并且创建在容器标签中
var container = document.getElementById("jsoneditor");
var options = {
mode: 'tree'
};
var editor = new JSONEditor(container, options);
给容器设置json数据
editor.set(json);
获取指定editor的json数据
var json = editor.get();
一个基本的编辑器就跑出来了,但是这还不够,需要自己多样化
使用react二次封装
App.js代码
import React, { Component } from 'react'
import JsonEditor from './JsonEditor';
import 'jsoneditor/dist/jsoneditor.css';
import './App.css';
export default class App extends Component {
constructor(props){
super(props)
this.state={
data:
{
"Array": [1, 2, 3],
"Boolean": true,
"Null": null,
"Number": 123,
"Object": {"a": "b", "c": "d"},
"String": "Hello World"
}
}
}
render() {
return (
<div>
<JsonEditor value={this.state.data}/>
</div>
)
}
}
JsonEditor代码
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
针对更多场景改造
import React, { PureComponent } from 'react'
import JSONEditor from 'jsoneditor'
import PropTypes from 'prop-types'
import 'jsoneditor/dist/jsoneditor.css'
/**
* JsonEditor
* @param {object} json 用于绑定的json数据
* @param {func} onChange 变化时的回调
* @param {func} getJson 为外部提供回去json的方法
* @param {func} onError 为外部提供json格式错误的回调
* @param {string} themeBgColor 为外部暴露修改主题色
*/
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