携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第3天,点击查看活动详情
是个前端就离不开JSON,之前一直使用各种站长工具,然后天天看广告,然后自己萌生了自己写JSON格式化工具的想法,于是自己撸了一个轮子。废话不多说,我们手写一个格式化json工具。。 干货从第四步开始,着急的同学直接看第三步,不影响阅读。
第一步,拿到JSON字符串
代码语言:javascript复制 let stringJson = JSON.stringify({ editor: { editor: { editor: { editor: 'aa' } } } });
第二步,放到一个textarea里面方便编辑
代码语言:javascript复制function Editor() {
// fetch('/tripdocs/test/api', { method: 'POST' });
// 这里写一个可以格式化的json
let stringJson = JSON.stringify({ editor: { editor: { editor: { editor: 'aa' } } } });
return <textarea className="editor" defaultValue={stringJson}></textarea>;
}
第三步,初步实现
代码语言:javascript复制function Editor() {
// fetch('/tripdocs/test/api', { method: 'POST' });
// 这里写一个可以格式化的json
let stringJson = JSON.stringify({ editor: { editor: { editor: { editor: 'aa' } } } });
stringJson = stringJson.replace(/{/gi, '{n');
stringJson = stringJson.replace(/}/gi, 'n}');
return <textarea className="editor" defaultValue={stringJson}></textarea>;
}
效果图如下
第四步,优化显示——简单处理object,增加空格
这一步,说明一下,json其实是一个树形结构。需要按照深度优先进行遍历。每深入一层就需要多加2个空格。
这时候需要树形结构,所以我放弃了直接用正则,转而使用递归的方式。
直接上方法
首先需要一个方法打印空格,这里利用数组进行操作
代码语言:javascript复制function printSpace(num: number) {
return new Array(num).fill(' ').join('');
}
接下来,我们需要处理传入的对象,但是我不知道,他是否合法是否有循环引用
这里利用JSON携带的函数取巧处理
代码语言:javascript复制function printJson(tObj: Object, i: number = 1) {
const count = i || 1;
// TODO 判断是不是纯净的object,这里先当纯净的处理 利用JSON parse
const obj = JSON.parse(JSON.stringify(tObj));
}
这里我们一共会遇到三类情况,纯净的Object、数组、其他基础类型的值。
其他基础类型:Number、String、Boolean、object、Null ps:不包含 undefined、Symbol(),会被 JSON.stringify 过滤
伪代码
代码语言:javascript复制 if (obj && Array.isArray(obj)) {
} else if (obj && typeof obj === 'object') {
} else {
}
重要的步骤来了,深度遍历。这里先只考虑纯净的object和其他基础类型的值
代码语言:javascript复制function printJson(tObj: Object, i: number = 0) {
const count = i || 0;
// TODO 判断是不是纯净的object,这里先当纯净的处理 利用JSON parse
const obj = JSON.parse(JSON.stringify(tObj));
if (obj && Array.isArray(obj)) {
} else if (obj && typeof obj === 'object') {
let str = '';
// 遍历object
Object.keys(obj).forEach(key => {
// 换行 加空格 给key加双引号 递归处理子对象
str = 'n' printSpace(count 1) '"' key '"' ' : ' printJson(obj[key], count 1);
// 最后加,
str = ',';
});
// 首部{不加空格,尾部}加空格
return `{${str}n${printSpace(count)}}`;
} else {
// string 类型加双引号
if (typeof obj === 'string') {
return '"' obj '"';
}
return obj;
}
}
function printSpace(num: number) {
return new Array(num).fill(' ').join('');
}
第五步,处理数组
数组最大的不同是,数组没有key
以下是完整代码
代码语言:javascript复制function printJson(tObj: Object, i: number = 0) {
const count = i || 0;
// TODO 判断是不是纯净的object,这里先当纯净的处理 利用JSON parse
const obj = JSON.parse(JSON.stringify(tObj));
if (obj && Array.isArray(obj)) {
let str = '';
Object.keys(obj).forEach(key => {
str = 'n' printSpace(count 1) printJson(obj[key], count 1);
str = ',';
});
return `[${str}n${printSpace(count)}]`;
} else if (obj && typeof obj === 'object') {
let str = '';
Object.keys(obj).forEach(key => {
str = 'n' printSpace(count 1) '"' key '"' ' : ' printJson(obj[key], count 1);
str = ',';
});
return `{${str}n${printSpace(count)}}`;
} else {
if (typeof obj === 'string') {
return '"' obj '"';
}
return obj;
}
}
function printSpace(num: number) {
return new Array(num).fill(' ').join('');
}
function Editor() {
let stringJson = printJson({
type: 'table',
row: 5,
column: 6,
isShow: null,
isDrag: undefined,
isDrag2: Symbol('ss'),
hwEach: [
['109px', '109px', '109px', '109px', '109px', '109px'],
['109px', '109px', '109px', '109px', '109px', '109px'],
],
});
// stringJson = stringJson.replace(/{/gi, '{n');
// stringJson = stringJson.replace(/}/gi, 'n}');
return (
<textarea
className="editor"
defaultValue={stringJson}
onContextMenu={e => {
e.preventDefault();
}}
></textarea>
);
}
此时效果如下