当前位置: 首页 > ai >正文

vue3实现JSON格式化和JSONPath提取功能

功能简介

1、JSON数据的格式化
2、通过JSONPath语法对格式化后的数据匹配提取

基础环境参考

vue3+flask+sqlite前后端项目实战

包安装

npm install jsonpath

在这里插入图片描述

src/views/JsonFormat.vue

<template><div class="json-formatter-container"><el-card class="box-card"><template #header><div class="card-header"><h1>JSON 格式化工具</h1><el-button class="back-button" type="info" @click="goBack" size="small">返回</el-button></div></template><div class="input-section"><el-inputv-model="inputJson"type="textarea":rows="10"placeholder="请粘贴JSON数据"resize="none"class="wider-input"/><div class="action-buttons"><el-buttontype="primary"@click="formatJson":disabled="!inputJson":loading="isFormatting">{{ isFormatting ? '格式化中...' : '格式化JSON数据' }}</el-button><el-button @click="clearAll" :disabled="!inputJson">清空JSON数据</el-button></div></div><div class="jsonpath-section"><el-inputv-model="jsonPathExpression"placeholder="请输入JSONPath表达式"class="jsonpath-input"/><el-button@click="applyJsonPath":disabled="!outputJson":loading="isApplyingJsonPath"class="jsonpath-button">{{ isApplyingJsonPath ? '处理中...' : '应用JSONPath' }}</el-button><el-button @click="clearJsonPath" :disabled="!jsonPathExpression" class="jsonpath-button">清空JSONPath</el-button></div><div class="output-section"><h3 class="output-title">匹配结果</h3><el-inputv-model="jsonPathResult"type="textarea":rows="10"readonlyresize="none"class="wider-input"/><div class="copy-section"><el-button@click="copyJsonPathResult":disabled="!jsonPathResult || isCopying":loading="isCopying"type="success"plain>{{ isCopying ? '复制中...' : '复制' }}</el-button></div></div></el-card></div>
</template><script>
import { ref } from 'vue';
import { ElMessage } from 'element-plus';
import { useRouter } from 'vue-router';
import jsonpath from 'jsonpath';export default {setup() {const router = useRouter();const inputJson = ref('');const outputJson = ref('');const jsonPathExpression = ref('');const jsonPathResult = ref('');const isFormatting = ref(false);const isApplyingJsonPath = ref(false);const isCopying = ref(false);const goBack = () => {router.push('/');};const parseContentRecursively = (data) => {if (typeof data === 'object' && data !== null) {for (const key in data) {const value = data[key];// 仅处理已经是对象/数组的值if (typeof value === 'object' && value !== null) {parseContentRecursively(value);}// 所有字符串值(包括JSON格式字符串)都保持原样}}};const formatJson = async () => {if (!inputJson.value.trim()) return;isFormatting.value = true;try {const parsed = JSON.parse(inputJson.value);parseContentRecursively(parsed);outputJson.value = JSON.stringify(parsed, null, 2);jsonPathResult.value = outputJson.value;ElMessage.success('JSON 格式化成功');} catch (error) {ElMessage.error(`格式化错误: ${error.message || '无效的JSON格式'}`);outputJson.value = '';jsonPathResult.value = '';} finally {isFormatting.value = false;}};const applyJsonPath = async () => {if (!jsonPathExpression.value.trim()) {jsonPathResult.value = outputJson.value;return;}isApplyingJsonPath.value = true;try {const parsed = JSON.parse(outputJson.value);let result = jsonpath.query(parsed, jsonPathExpression.value);jsonPathResult.value = JSON.stringify(result.length === 1 ? result[0] : result,null,2);ElMessage.success('JSONPath 应用成功');} catch (error) {ElMessage.error(`JSONPath 错误: ${error.message || '无效表达式'}`);jsonPathResult.value = '';} finally {isApplyingJsonPath.value = false;}};const copyJsonPathResult = async () => {if (!jsonPathResult.value) {ElMessage.warning('没有可复制的内容');return;}isCopying.value = true;try {if (navigator.clipboard?.writeText) {await navigator.clipboard.writeText(jsonPathResult.value);ElMessage.success('复制成功');} else {const textarea = document.createElement('textarea');textarea.value = jsonPathResult.value;textarea.style.position = 'fixed';textarea.style.opacity = '0';document.body.appendChild(textarea);textarea.select();try {const success = document.execCommand('copy');if (!success) throw new Error('复制命令被拒绝');ElMessage.success('复制成功');} finally {document.body.removeChild(textarea);}}} catch (err) {ElMessage.error(`复制失败: ${err.message || '未知错误'}`);} finally {isCopying.value = false;}};const clearAll = () => {inputJson.value = '';outputJson.value = '';jsonPathExpression.value = '';jsonPathResult.value = '';};const clearJsonPath = () => {jsonPathExpression.value = '';};return {inputJson,outputJson,jsonPathExpression,jsonPathResult,isFormatting,isApplyingJsonPath,isCopying,goBack,formatJson,applyJsonPath,copyJsonPathResult,clearAll,clearJsonPath};}
};
</script><style scoped>
.json-formatter-container {max-width: 1000px;margin: 20px auto;padding: 0 20px;overflow-x: hidden;
}.card-header {display: flex;justify-content: space-between;align-items: center;
}.card-header h1 {margin: 0;font-size: 18px;color: #333;
}.back-button {background: #42b983;color: white;border: none;padding: 8px 12px;border-radius: 4px;cursor: pointer;transition: background 0.2s;
}.back-button:hover {background: #3aa876;
}.input-section {margin-bottom: 20px;
}.action-buttons {margin-top: 15px;display: flex;gap: 10px;justify-content: flex-end;
}.jsonpath-section {display: flex;align-items: center;margin-top: 30px;
}.jsonpath-input {flex-grow: 1;margin-right: 10px;
}.jsonpath-button {flex-shrink: 0;margin-left: 5px;
}.output-section {margin-top: 30px;
}.output-title {margin-bottom: 10px;font-size: 16px;color: #333;text-align: left;
}.copy-section {margin-top: 15px;display: flex;justify-content: flex-end;
}.wider-input {width: 100%;overflow-y: hidden;
}
</style>

在这里插入图片描述

src/router/index.js

import JsonFormat from '../views/JsonFormat.vue';{ path: '/json_format', component: JsonFormat },

在这里插入图片描述

启动运行

npm run dev

在这里插入图片描述

页面初始化效果

http://localhost:5173/json_format

在这里插入图片描述

json格式化效果

在这里插入图片描述

通过JSONPath提取效果

在这里插入图片描述

JSONPath相关补充

在这里插入图片描述

JSONPath基础语法示例

{"store": {"book": [{ "title": "Book A", "price": 8.95 },{ "title": "Book B", "price": 12.99 },{ "title": "Book C", "price": 9.99 }],"location": "Beijing"}
}
表达式结果
$.store.book[0].title“Book A”(第一本书的标题)
$…price[8.95, 12.99, 9.99](所有价格)
$.store.book[*].title[“Book A”, “Book B”, “Book C”](所有书名)
$.store.book[?(@.price > 10)][{“title”: “Book B”, “price”: 12.99}](价格大于 10 的书)
$…book[-1:][{“title”: “Book C”, “price”: 9.99}](最后一本书)
$.store.*所有 store 的子节点(book 数组和 location 字符串)
http://www.xdnf.cn/news/6112.html

相关文章:

  • 10、面向对象技术★★★★★30‘
  • 移动端巡检点检,让设备管理更便捷高效
  • 当数控编程“联姻”AI:制造工厂的“智能大脑”如何炼成?
  • .NET NativeAOT 指南
  • CGO中引入 <cstddef> <vector> fatal error: cstddef: No such file or directory 失败的原因
  • Llama:开源的急先锋
  • 基于springboot+vue的医院门诊管理系统
  • 南审计院考研分享会 经验总结
  • Android多媒体——媒体start流程分析(十三)
  • PinkWallet如何打通数字资产与传统金融的最后一公里
  • Vue百日学习计划Day1-3天详细计划-Gemini版
  • 计算机组成与体系结构:缓存设计概述(Cache Design Overview)
  • spring中的@MapperScan注解详解
  • 【RabbitMq】无法打开 RabbitMq 管理插件的问题
  • Python基础入门
  • 文件名是 ‪E:\20250512_191204.mp4, EV软件录屏,未保存直接关机损坏, 如何修复?
  • 机器学习入门案例:鸢尾花分类与AI辅助
  • 机器人示教操作
  • 微型PCB打样厂家选型指南
  • 全局优化搜索高次方程的解
  • C++学习之打车软件git版本控制
  • RabbitMQ 快速上手:安装配置与 HelloWorld 实践(二)
  • 【SSL证书系列】客户端如何验证https网站服务器发的证书是否由受信任的根证书签发机构签发
  • 【原创】使用阿里云存放一个临时共享的文件
  • FunASR:语音识别与合成一体化,企业级开发实战详解
  • 论MCU如何在Fatfs中使用Flash接口的方法
  • 前端面试每日三题 - Day 34
  • 白盒测试——基本路径测试法
  • copy_paste
  • 如何实现一个运动会计分系统?(C语言版)