{"record":{"id":"a4578186cea509bb","repo":"jeecgboot/JeecgBoot","slug":"addcomponent-type-name","errorCode":null,"errorMessage":"【addComponent】不能使用\"${type}\"作为组件的name，因为这是关键字。","messagePattern":"【addComponent】不能使用\"(.+?)\"作为组件的name，因为这是关键字。","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"jeecgboot-vue3/src/components/jeecg/JVxeTable/src/componentMap.ts","lineNumber":47,"sourceCode":"/** 定义不能用于注册的关键字 */\nexport const excludeKeywords: Array<JVxeTypes> = [\n  JVxeTypes.hidden,\n  JVxeTypes.rowNumber,\n  JVxeTypes.rowCheckbox,\n  JVxeTypes.rowRadio,\n  JVxeTypes.rowExpand,\n];\n\n/**\n * 注册组件\n *\n * @param type 组件 type\n * @param component Vue组件\n * @param spanComponent 显示组件，可空，默认为 JVxeNormalCell 组件\n */\nexport function addComponent(type: JVxeTypes, component: JVxeVueComponent, spanComponent?: JVxeVueComponent) {\n  if (excludeKeywords.includes(type)) {\n    throw new Error(`【addComponent】不能使用\"${type}\"作为组件的name，因为这是关键字。`);\n  }\n  if (componentMap.has(type)) {\n    throw new Error(`【addComponent】组件\"${type}\"已存在`);\n  }\n  componentMap.set(type, component);\n  if (spanComponent) {\n    componentMap.set(type + spanEnds, spanComponent);\n  }\n  // 代码逻辑说明: 【issues/860】生成的一对多代码，热更新之后点击新增卡死[暂时先解决]\n  import.meta.env.DEV && (window[JVxeComponents] = componentMap);\n}\n\nexport function deleteComponent(type: JVxeTypes) {\n  componentMap.delete(type);\n  componentMap.delete(type + spanEnds);\n  // 代码逻辑说明: 【issues/860】生成的一对多代码，热更新之后点击新增卡死[暂时先解决]\n  import.meta.env.DEV && (window[JVxeComponents] = componentMap);\n}","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/jeecgboot/JeecgBoot/blob/96fb33f5ec68516da0b0147da06b2eb0419e063a/jeecgboot-vue3/src/components/jeecg/JVxeTable/src/componentMap.ts#L29-L65","documentation":"addComponent registers a JVxeTable cell component under a JVxeTypes key. A fixed list (excludeKeywords) contains reserved type names — hidden, rowNumber, rowCheckbox, rowRadio, rowExpand — that are internal system column types, not editable cells. Registering a custom component under one of these would shadow built-in behavior, so the guard rejects it. This is a programming-error guard, not a runtime data error.","triggerScenarios":"Calling addComponent(JVxeTypes.rowNumber, myComponent) or passing any of the five reserved JVxeTypes values as the first argument during third-party component registration (typically in registerThirdComp.ts or an app plugin).","commonSituations":"Building a custom JVxeTable plugin and accidentally choosing a type name that collides with a built-in; copy-pasting a registration block and forgetting to change the type; iterating over all JVxeTypes enum values to auto-register.","solutions":["Choose a non-reserved JVxeTypes value (or add a new entry to the enum) for your custom component.","Check the excludeKeywords list before calling addComponent and skip reserved names.","If extending the enum, do not reuse hidden/rowNumber/rowCheckbox/rowRadio/rowExpand names."],"exampleFix":"// before\naddComponent(JVxeTypes.rowNumber, MyCell); // reserved keyword, throws\n\n// after — use a custom, non-reserved type\naddComponent(JVxeTypes.myCustomType, MyCell);","handlingStrategy":"validation","validationCode":"import { excludeKeywords } from './componentMap';\nfunction safeAddComponent(type, component, spanComponent?) {\n  if (excludeKeywords.includes(type)) {\n    console.warn(`Skipping reserved type ${type}`);\n    return;\n  }\n  addComponent(type, component, spanComponent);\n}","typeGuard":"const isReservedType = (t: JVxeTypes): boolean => excludeKeywords.includes(t);","tryCatchPattern":"try {\n  addComponent(type, component);\n} catch (e) {\n  // type is reserved; choose another name\n}","preventionTips":["Check excludeKeywords before registering custom cell types.","Add new types to the JVxeTypes enum instead of reusing reserved names.","Write a unit test asserting your registrations avoid reserved names."],"tags":["vxe-table","component-registration","frontend","programming-error"],"backgroundTag":null,"analyzedSha":"96fb33f5ec68516da0b0147da06b2eb0419e063a","analyzedAt":"2026-08-14T00:04:16.786Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}