Nuxt3/Vue3中JSON-LD转JS类对象的方案及报错解决
解决JSON-LD转树形JavaScript对象的方案
一、先解决你遇到的两个库报错问题
1. json-schema-to-ts 找不到FromSchema导出
这个库的最新版本导出结构有变化,注意要使用类型导入,在TypeScript中需添加type关键字:
import type { FromSchema } from 'json-schema-to-ts';
如果是在Nuxt3的JavaScript环境下使用,这个库主要用于TypeScript类型推导,实际意义不大,因为JS不需要静态类型校验。
2. json-schema-to-typescript 的__dirname未定义错误
Nuxt3/Vue3采用ESM模块规范,__dirname是CommonJS专属变量,ESM环境中不存在。可以用import.meta.url替代实现文件路径获取:
import { fileURLToPath } from 'url'; import { dirname, join } from 'path'; import { compileFromFile } from 'json-schema-to-typescript'; import fs from 'fs/promises'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); // 拼接Schema文件路径并编译 compileFromFile(join(__dirname, 'your-schema.json')) .then(tsContent => fs.writeFile('output.d.ts', tsContent)) .catch(err => console.error(err));
注意:这个库仅生成TypeScript类型定义,不能直接输出带父子类关系的JavaScript对象结构,可能不符合你的核心需求。
二、通用JSON-LD转树形JS对象方案
1. 基于@json-tools/json-schema-traverse遍历Schema
这个库可递归遍历JSON-LD结构,自动提取类、子类与属性关系,你可以自定义逻辑生成树形对象:
import traverse from '@json-tools/json-schema-traverse'; function buildClassTree(schema) { const classTree = {}; traverse(schema, { enter(node, parent, key, path) { // 识别类定义节点(基于JSON-LD的object类型与properties字段) if (node.type === 'object' && node.properties) { const className = node.title || path.join('.'); classTree[className] = { properties: {}, children: {} }; // 解析属性,递归处理嵌套类 for (const propName in node.properties) { const propSchema = node.properties[propName]; if (propSchema.type === 'object' && propSchema.properties) { const childClassName = propSchema.title || `${className}.${propName}`; classTree[className].children[childClassName] = buildClassTree(propSchema); } else { classTree[className].properties[propName] = propSchema.type || 'unknown'; } } // 处理继承关系(allOf字段对应父类引用) if (node.allOf) { node.allOf.forEach(parentSchema => { if (parentSchema.$ref) { const refPath = parentSchema.$ref.replace('#/', ''); const parentClass = classTree[refPath]; if (parentClass) { // 合并父类属性与子类 Object.assign(classTree[className].properties, parentClass.properties); Object.assign(classTree[className].children, parentClass.children); } } }); } } } }); return classTree; } // 使用示例 import jsonLdSchema from '~/schemas/your-jsonld-schema.json'; const classTree = buildClassTree(jsonLdSchema);
2. 自定义递归解析逻辑(无需额外依赖)
如果不想引入第三方库,可以直接基于JSON-LD核心字段(@type、properties、rdfs:subClassOf)写递归解析函数:
function parseJsonLdClass(schema, classMap = {}) { // 提取类名,优先用@type或title const className = schema['@type'] || schema.title || 'AnonymousClass'; const classDef = { properties: {}, parentClasses: [], children: [] }; // 解析属性 if (schema.properties) { Object.entries(schema.properties).forEach(([propName, propDef]) => { if (propDef['@type'] || propDef.properties) { // 属性为嵌套类,递归解析 const { className: propClassName, classMap: updatedMap } = parseJsonLdClass(propDef, classMap); classDef.properties[propName] = propClassName; Object.assign(classMap, updatedMap); } else { classDef.properties[propName] = propDef.type || 'unknown'; } }); } // 解析子类关系 if (schema['rdfs:subClassOf']) { const parentClassName = schema['rdfs:subClassOf']['@id'] || schema['rdfs:subClassOf'].title; classDef.parentClasses.push(parentClassName); if (classMap[parentClassName]) { classMap[parentClassName].children.push(className); } } classMap[className] = classDef; return { className, classDef, classMap }; } // 使用示例 import jsonLdSchema from '~/schemas/complex-jsonld-schema.json'; const { classMap } = parseJsonLdClass(jsonLdSchema);
三、Nuxt3/Vue3环境适配
在Nuxt3中读取本地JSON-LD文件时,需使用ESM导入方式:
// 在组件或插件中 import jsonLdSchema from '~/schemas/your-schema.json'; const classTree = buildClassTree(jsonLdSchema); // 可将classTree存入Pinia状态管理,或直接在组件中使用
内容的提问来源于stack exchange,提问作者BATMAN_2008
相关产品推荐
相关产品推荐

