相信很多同学都用过网上的在线JSON格式化工具来将杂乱的JSON数据转换成易于我们阅读和编辑的格式。那么,你有没有想过自己动手实现一个这样的工具呢?今天,我将介绍如何使用Vue.js来构建一个简单的JSON格式化工具。
1、自动补全
输入”(“、”{“、”[“将会自动补全另一半
2、自动删除
删除括号时也会自动删除另一半
3、括号匹配
点击括号会高亮另一半括号,方便定位
4、支持ctrl+z撤销和ctrl+y重做功能
5、编辑器根据字符串的换行计算行号并展示
{{ jsonObj }}
/*index.ts*/
import { nextTick } from 'vue';
// 获取文本框的值
export const handleTextareaInput = (viewJsonStr, event) => {
const textarea = event.target;
const newValue = textarea.value;
viewJsonStr.value = newValue;
};
// 设置自动补全
export const setAutoKey = (viewJsonStr, event) => {
const textarea: any = document.getElementById('rightNum');
if (event.key === "'" || event.key === '"') {
event.preventDefault(); // 阻止默认行为
const selectedText = textarea.value.substring(textarea.selectionStart, textarea.selectionEnd);
const newText = `${event.key}` + selectedText + `${event.key}`;
const cursorPosition = textarea.selectionStart + 1;
textarea.value =
textarea.value.substring(0, textarea.selectionStart) +
newText +
textarea.value.substring(textarea.selectionEnd);
textarea.setSelectionRange(cursorPosition, cursorPosition);
} else if (event.key === '(') {
event.preventDefault(); // 阻止默认行为
const selectedText = textarea.value.substring(textarea.selectionStart, textarea.selectionEnd);
const newText = '(' + selectedText + ')';
const cursorPosition = textarea.selectionStart + 1;
textarea.value =
textarea.value.substring(0, textarea.selectionStart) +
newText +
textarea.value.substring(textarea.selectionEnd);
textarea.setSelectionRange(cursorPosition, cursorPosition);
} else if (event.key === '[') {
event.preventDefault(); // 阻止默认行为
const selectedText = textarea.value.substring(textarea.selectionStart, textarea.selectionEnd);
const newText = '[' + selectedText + ']';
const cursorPosition = textarea.selectionStart + 1;
textarea.value =
textarea.value.substring(0, textarea.selectionStart) +
newText +
textarea.value.substring(textarea.selectionEnd);
textarea.setSelectionRange(cursorPosition, cursorPosition);
} else if (event.key === '{') {
event.preventDefault(); // 阻止默认行为
const selectedText = textarea.value.substring(textarea.selectionStart, textarea.selectionEnd);
const newText = '{' + selectedText + '}';
const cursorPosition = textarea.selectionStart + 1;
textarea.value =
textarea.value.substring(0, textarea.selectionStart) +
newText +
textarea.value.substring(textarea.selectionEnd);
textarea.setSelectionRange(cursorPosition, cursorPosition);
}
viewJsonStr.value = textarea.value;
};
/*------------------------------------------------括号高亮------------------------------------------------------------*/
const findOpeningBracketIndex = (text, startIndex, char) => {
const openingBrackets = {
']': '[',
'}': '{',
')': '(',
};
let count = 0;
for (let i = startIndex; i >= 0; i--) {
if (text.charAt(i) === char) {
count++;
} else if (text.charAt(i) === openingBrackets[char]) {
count--;
if (count === 0) {
return i;
}
}
}
return -1;
};
const findClosingBracketIndex = (text, startIndex, char) => {
const closingBrackets = {
'[': ']',
'{': '}',
'(': ')',
};
let count = 0;
for (let i = startIndex; i < text.length; i++) {
if (text.charAt(i) === char) {
count++;
} else if (text.charAt(i) === closingBrackets[char]) {
count--;
if (count === 0) {
return i;
}
}
}
return -1;
};
const isBracket = (char) => {
return ['[', ']', '{', '}', '(', ')'].includes(char);
};
// 点击括号寻找对应另一半
export const handleClick = (event) => {
const textarea: any = document.getElementById('rightNum');
const { selectionStart, selectionEnd, value } = textarea;
const clickedChar = value.charAt(selectionStart);
if (isBracket(clickedChar)) {
const openingBracketIndex = findOpeningBracketIndex(value, selectionStart, clickedChar);
const closingBracketIndex = findClosingBracketIndex(value, selectionStart, clickedChar);
if (openingBracketIndex !== -1) {
textarea.setSelectionRange(openingBracketIndex, openingBracketIndex + 1);
} else if (closingBracketIndex !== -1) {
textarea.setSelectionRange(closingBracketIndex, closingBracketIndex + 1);
}
}
};
/*键盘事件*/
export function handleClickEnter(viewJsonStr, event) {
if (event.key == 'Enter') {
const textarea = event.target;
const cursorPosition: any = textarea.selectionStart; // 获取光标位置
const value = textarea.value;
if (
(value[cursorPosition - 1] === '{' && value[cursorPosition] == '}') ||
(value[cursorPosition - 1] === '[' && value[cursorPosition] == ']')
) {
textarea.value = value.slice(0, cursorPosition) + '\n' + value.slice(cursorPosition);
textarea.setSelectionRange(cursorPosition, cursorPosition);
viewJsonStr.value = textarea.value;
// 将光标移动到插入的空格后面
setTimeout(() => {
handleTabKey(syntheticEvent);
}, 30);
}
}
}
// 新建tab按键对象
const syntheticEvent = new KeyboardEvent('keydown', {
key: 'Tab',
});
// 按下tab键时的操作
export const handleTabKey = (event) => {
const textarea: any = document.getElementById('rightNum');
const { selectionStart, selectionEnd } = textarea;
const tabSpaces = ' '; // 4 spaces
event.preventDefault();
// 在当前光标位置插入4个空格
textarea.value =
textarea.value.substring(0, selectionStart) +
tabSpaces +
textarea.value.substring(selectionEnd);
// 将光标向右移动4个空格
textarea.selectionStart = selectionStart + tabSpaces.length;
textarea.selectionEnd = selectionStart + tabSpaces.length;
};
// 按下Backspace按键时
export function handleBackspace(viewJsonStr, event) {
const textarea = event.target;
const cursorPosition = textarea.selectionStart;
const textBeforeCursor = viewJsonStr.value.slice(0, cursorPosition);
const textAfterCursor = viewJsonStr.value.slice(cursorPosition);
if (
(textBeforeCursor.endsWith('"') && textAfterCursor.startsWith('"')) ||
(textBeforeCursor.endsWith("'") && textAfterCursor.startsWith("'")) ||
(textBeforeCursor.endsWith('[') && textAfterCursor.startsWith(']')) ||
(textBeforeCursor.endsWith('{') && textAfterCursor.startsWith('}')) ||
(textBeforeCursor.endsWith('(') && textAfterCursor.startsWith(')'))
) {
event.preventDefault(); // 阻止默认的删除行为
viewJsonStr.value = textBeforeCursor.slice(0, -1) + textAfterCursor.slice(1);
nextTick(() => {
textarea.selectionStart = cursorPosition - 1;
textarea.selectionEnd = cursorPosition - 1;
}).then((r) => {});
}
}
const testStr = ref('123');
这个JSON编辑器不仅能够让你方便地格式化JSON字符串,还能帮你去掉不必要的空格。而且,它的全屏功能让编辑更加顺畅。最酷的是,它还能实时告诉你格式化的进度,如果遇到问题了,控制台会详细告诉你哪里出错了,这样你就能快速找到问题并解决它。编辑器还能精确地计算行号,这对于查找问题也是很有帮助的。而且,它还有自动补全、自动删除和括号匹配这些贴心的功能,让你的编辑工作变得更加轻松。如果你不小心做错了,也不用担心,因为它支持撤销和重做。希望它能帮助到大家,让我们的工作更加愉快!