使用cursor ai 开发 UniApp JSON 工具开发文档
使用cursor ai 开发 UniApp JSON 工具开发文档
1. 需求背景
在开发过程中,我们经常需要处理 JSON 数据,包括格式化、压缩、转义、Unicode 转换等操作。为了提高开发效率,我们决定开发一个功能完善的 JSON 工具页面,集成多种常用功能,并提供友好的用户界面和错误提示。
主要功能需求包括:
- JSON 格式化与压缩
- JSON 转义与去转义
- Unicode 与中文互转
- 带行号的代码编辑器
- 精确的错误提示
- 复制与清空功能
在线演示
演示地址: http://demo.xiyueta.com/case/web20250222/#/pages/debug/json
测试账号: demo
测试密码: 123456
使用效果
json工具
2. 技术选型
- 前端框架:UniApp + Vue 3 (Composition API)
- JSON 解析:jsonlint-mod(第三方库,提供更详细的错误信息)
- UI 组件:自定义组件,不依赖第三方 UI 库
- 样式:SCSS 预处理器
3. 功能实现
3.1 带行号的代码编辑器
实现带行号的代码编辑器是本项目的核心挑战之一。我们尝试了多种方案,最终采用了一种简单而有效的实现方式。
初始尝试:绝对定位 + 滚动同步
最初,我们尝试将行号区域和编辑区域分开,通过监听编辑区域的滚动事件来同步行号区域的滚动位置:
<view class="editor-main">
<view class="line-numbers">
<view class="line-numbers-content" :style="{ transform: `translateY(-${scrollTop}px)` }">
<view v-for="n in lineCount" :key="n" class="line-number">{{ n }}</view>
</view>
</view>
<textarea
v-model="inputText"
class="json-editor"
@scroll="onScroll"
ref="editorRef"
/>
</view>
<script>
// 处理滚动同步
const onScroll = (e) => {
scrollTop.value = e.detail.scrollTop
}
</script>
问题:这种方法在不同平台上表现不一致,特别是在小程序中,滚动事件的处理和 DOM 操作存在限制,导致滚动同步不准确。
最终解决方案:单一滚动容器
最终,我们采用了一个更简单、更可靠的方法:将行号和编辑区域放在同一个滚动容器内,利用 flex 布局实现并排显示:
<scroll-view class="editor-scroll" scroll-y>
<view class="editor-content">
<view class="line-numbers">
<view v-for="n in lineCount" :key="n" class="line-number">{{ n }}</view>
</view>
<textarea
v-model="inputText"
class="json-editor"
:maxlength="-1"
ref="editorRef"
/>
</view>
</scroll-view>
.editor-content {
display: flex;
min-height: 100%;
.line-numbers {
width: 80rpx;
flex-shrink: 0;
background: #fafafa;
border-right: 1px solid #ebeef5;
padding: 20rpx 0;
.line-number {
height: 42rpx;
line-height: 42rpx;
text-align: right;
padding-right: 10rpx;
color: #909399;
font-size: 28rpx;
}
}
.json-editor {
flex: 1;
min-height: 100%;
height: auto;
padding: 20rpx;
font-size: 28rpx;
line-height: 42rpx;
font-family: Consolas, Monaco, monospace;
white-space: pre;
border: none;
outline: none;
resize: none;
}
}
这种方法的优势在于:
- 行号和内容在同一个滚动容器中,自然同步滚动
- 不需要额外的 JavaScript 代码来处理滚动同步
- 跨平台兼容性好
- 实现简单,性能更好
3.2 JSON 解析与错误处理
最初,我们使用浏览器内置的 JSON.parse()
方法进行 JSON 解析,但发现它提供的错误信息有限,难以精确定位错误位置。
问题:错误定位不准确
使用 JSON.parse()
时,错误信息通常只包含字符位置,没有行号和列号信息:
try {
const obj = JSON.parse(inputText.value)
// 处理成功情况
} catch (e) {
errorMsg.value = e.message
// 尝试从错误信息中提取位置信息
errorPosition.value = getErrorPosition(inputText.value, e)
}
这种方法难以准确定位错误位置,特别是对于复杂的 JSON 结构。
解决方案:使用 jsonlint-mod
我们引入了 jsonlint-mod
库,它提供更详细的错误信息,包括准确的行号和列号:
import jsonlint from 'jsonlint-mod'
// 格式化 JSON
const format = () => {
try {
if (!inputText.value) return
errorMsg.value = ''
errorPosition.value = null
try {
const obj = jsonlint.parse(inputText.value)
inputText.value = formatJsonPreserveUnicode(obj, 4)
outputText.value = ''
} catch (e) {
const errorInfo = parseJsonlintError(e.message)
errorPosition.value = {
line: errorInfo.line,
column: errorInfo.column
}
errorMsg.value = errorInfo.message
}
} catch (e) {
errorMsg.value = e.message
}
}
// 解析 jsonlint 错误信息
const parseJsonlintError = (errorMessage) => {
const lineMatch = errorMessage.match(/line (\d+)/)
const columnMatch = errorMessage.match(/column (\d+)/)
return {
line: lineMatch ? parseInt(lineMatch[1]) : 0,
column: columnMatch ? parseInt(columnMatch[1]) : 0,
message: errorMessage
}
}
这样,我们就能准确显示 JSON 中的错误位置,并提供有用的错误提示信息。
3.3 Unicode 编码处理问题
在实现 JSON 格式化功能时,我们发现一个问题:当 JSON 中包含 Unicode 编码的中文字符时,格式化后这些字符被错误地转义了两次。
问题:Unicode 编码被双重转义
例如,原始 JSON 中的 "\u83b7\u53d6\u6210\u529f"
表示 Unicode 编码的中文字符串 “获取成功”,但格式化后变成了 "\\u83b7\\u53d6\\u6210\\u529f"
。
问题出在 JSON 解析和格式化的过程中:
JSON.parse()
解析时会自动将 Unicode 编码转换为实际的中文字符JSON.stringify()
格式化时会将所有非 ASCII 字符(如中文)转换为 Unicode 编码- 由于直接将结果赋值给文本框,所以显示的是转义后的形式
解决方案:自定义格式化函数
我们实现了一个自定义的 JSON 格式化函数,它能够保留原始的 Unicode 编码:
// 自定义 JSON 格式化函数,保留 Unicode 编码
const formatJsonPreserveUnicode = (json, indent = 4) => {
let parsed
if (typeof json === 'string') {
parsed = JSON.parse(json)
} else {
parsed = json
}
// 使用正则表达式保留 Unicode 编码
return JSON.stringify(parsed, null, indent)
.replace(/\\\\u([0-9a-fA-F]{4})/g, '\\u$1')
}
这个函数确保在格式化和压缩 JSON 时,Unicode 编码的字符保持原样,不会被错误地转义两次。
3.4 Unicode 与中文互转功能
为了增强工具的实用性,我们添加了 Unicode 与中文互转功能:
// Unicode 转中文
const unicodeToChinese = () => {
try {
if (!inputText.value) return
errorMsg.value = ''
errorPosition.value = null
// Unicode 转中文
const result = inputText.value.replace(/\\u([0-9a-fA-F]{4})/g, (match, grp) => {
return String.fromCharCode(parseInt(grp, 16))
})
// 结果直接显示在输入框中
inputText.value = result
// 清空输出文本,触发成功提示
outputText.value = ''
} catch (e) {
errorMsg.value = e.message
}
}
// 中文转 Unicode
const chineseToUnicode = () => {
try {
if (!inputText.value) return
errorMsg.value = ''
errorPosition.value = null
// 中文转 Unicode
const result = inputText.value.replace(/[\u4e00-\u9fa5]/g, (match) => {
return '\\u' + match.charCodeAt(0).toString(16).padStart(4, '0')
})
// 结果直接显示在输入框中
inputText.value = result
// 清空输出文本,触发成功提示
outputText.value = ''
} catch (e) {
errorMsg.value = e.message
}
}
这两个功能使用正则表达式实现,能够准确地进行 Unicode 与中文的互相转换。
3.5 用户体验优化
为了提供更好的用户体验,我们实现了以下优化:
-
操作结果直接显示在输入框:所有操作(格式化、压缩、转义等)的结果直接显示在 JSON 文本框中,方便用户继续编辑。
-
成功提示:当操作成功时,在解析结果区域显示友好的成功提示:“老铁,这个JSON格式,没毛病。”
-
错误提示:当 JSON 格式有误时,显示详细的错误信息,包括错误行号、错误内容和期望的值类型。
-
复制功能:提供一键复制功能,方便用户复制处理后的 JSON 文本。
4. 遇到的问题及解决方案
4.1 滚动同步问题
问题:最初尝试使用两个独立的滚动区域,通过 JavaScript 同步滚动位置,但在不同平台上表现不一致。
解决方案:将行号和编辑区域放在同一个滚动容器内,利用 flex 布局实现并排显示,自然同步滚动。
4.2 行高对齐问题
问题:行号和文本内容的行高不一致,导致滚动时对不齐。
解决方案:为行号和编辑区域设置相同的行高和内边距,确保完美对齐。
.line-number, .json-editor {
height: 42rpx;
line-height: 42rpx;
}
4.3 错误定位问题
问题:使用浏览器内置的 JSON.parse()
难以准确定位错误位置。
解决方案:引入 jsonlint-mod
库,它提供更详细的错误信息,包括准确的行号和列号。
4.4 Unicode 编码双重转义问题
问题:JSON 中的 Unicode 编码在格式化后被错误地转义了两次。
解决方案:实现自定义的 JSON 格式化函数,确保 Unicode 编码保持原样。
4.5 跨平台兼容性问题
问题:不同平台(H5、小程序、App)对 DOM 操作和事件处理的支持不同。
解决方案:使用更简单的布局结构和更少的 JavaScript 代码,减少对平台特定 API 的依赖。
5. 总结
5.1 成功之处
- 功能完善:实现了 JSON 格式化、压缩、转义、Unicode 转换等多种功能,满足了开发过程中的各种需求。
- 用户体验好:提供了友好的界面、精确的错误提示和便捷的操作方式,提高了使用效率。
- 跨平台兼容:通过精心设计的布局和代码,确保了在各平台上的一致表现。
- 代码质量高:采用了 Vue 3 Composition API,代码结构清晰,易于维护和扩展。
5.2 经验教训
- 从简单开始:在 UniApp 开发中,应该优先考虑简单的实现方式,避免过度依赖平台特定 API。
- 减少 DOM 操作:尽量减少直接的 DOM 操作,特别是在跨平台场景下。
- 利用布局特性:巧妙利用 CSS 布局特性可以解决许多看似复杂的问题。
- 测试多平台:在开发过程中,应该在多个平台上测试,及早发现兼容性问题。
- 注意细节:像 Unicode 编码这样的细节问题,可能会影响用户体验,需要特别注意。
5.3 未来改进
- 添加更多功能:如 JSON 与 XML 互转、JSON 与 YAML 互转等。
- 添加语法高亮:实现 JSON 语法高亮,提高可读性。
- 优化性能:对大型 JSON 文件的处理性能进行优化。
- 增加历史记录:添加操作历史记录功能,方便用户回退操作。
- 支持文件导入导出:添加从文件导入和导出到文件的功能。
通过这个项目,我们不仅开发了一个实用的 JSON 工具,还积累了宝贵的 UniApp 跨平台开发经验,特别是在复杂 UI 交互和文本处理方面的实践经验,为未来的项目开发奠定了基础。
关于作者
如果本文章对您有所帮助,欢迎交流和探讨技术问题。
QQ: 313801120
更多文章: www.xiyueta.com/
希望能一起成长,共同探索更多开发技巧!