san
Generate Vue.js components with specified features like templates, styles, computed properties, lifecycle hooks, and TypeScript support by providing component names and required functionality.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| componentName | Yes | 组件名称(使用PascalCase命名规范) | |
| features | No | 需要包含的特性,使用逗号分隔:template-模板, style-样式, computed-计算属性, lifecycle-生命周期, typescript-TypeScript支持。 | |
| description | No | 组件的功能描述(可选) | |
| selectedComponents | No | 选择使用的组件列表 |
Implementation Reference
- src/tools/san/index.ts:52-140 (handler)The execute function that implements the core logic of the 'san' tool. It generates San component code (TypeScript and LESS) based on input parameters, using templates from config and Cosmic UI components.export async function execute(args: SanToolParams) { try { const {componentName, description = ''} = args; // 如果没有提供componentName,返回组件列表 if (!componentName) { return { content: [ { type: 'text' as const, text: JSON.stringify( { message: '获取Cosmic组件列表成功', components: COSMIC_COMPONENTS, }, null, 2 ), }, ], }; } // 确保Button组件总是被包含 const finalComponents = [...new Set(['Button'])]; // 生成组件代码 let tsCode = COMPONENT_TEMPLATE; const imports = finalComponents.length > 0 ? generateImports(finalComponents) : ''; const components = finalComponents.length > 0 ? generateComponentRegistrations(finalComponents) : ''; // 替换模板变量 tsCode = tsCode.replace('{{imports}}', imports); tsCode = tsCode.replace('{{components}}', components); tsCode = tsCode.replace(/Props/g, `${componentName}Props`); tsCode = tsCode.replace(/State/g, `${componentName}State`); tsCode = tsCode.replace(/{{componentName}}/g, `${componentName}`); // 添加注释 const componentComment = `/**\n * ${componentName} 组件\n${description ? ` * ${description}\n` : ''} */\n`; tsCode = componentComment + tsCode; // 生成样式代码 const styleCode = STYLE_TEMPLATE.replace( /{{componentName}}/g, toKebabCase(`${componentName}`) ); return { content: [ { type: 'text' as const, text: JSON.stringify( { message: `成功生成 ${componentName} 组件代码`, components: COSMIC_COMPONENTS, files: [ { code: tsCode, filename: `${componentName}/index.ts`, }, { code: styleCode, filename: `${componentName}/index.less`, }, ], }, null, 2 ), }, ], }; } catch (error) { return { content: [ { type: 'text' as const, text: `错误: ${error instanceof Error ? error.message : '未知错误'}`, }, ], isError: true, }; } }
- src/tools/san/index.ts:29-49 (schema)Zod-based input schema for the 'san' tool parameters and corresponding TypeScript type definition.export const schema = { componentName: z.string().describe('组件名称(使用PascalCase命名规范)'), features: z .string() .optional() .describe( '需要包含的特性,使用逗号分隔:template-模板, style-样式, computed-计算属性, lifecycle-生命周期, typescript-TypeScript支持。' ), description: z.string().optional().describe('组件的功能描述(可选)'), selectedComponents: z .array(z.string()) .optional() .describe('选择使用的组件列表'), }; export type SanToolParams = { componentName: string; description?: string; features?: string; selectedComponents?: string[]; };
- src/index.ts:11-12 (registration)Registration of the 'san' tool on the MCP server, linking the schema and execute handler.// 注册 San 工具 server.tool('san', sanTool.schema, sanTool.execute);
- src/tools/san/index.ts:8-27 (helper)Helper functions used in the execute handler: toKebabCase for naming, generateImports for import statements, generateComponentRegistrations for component registry.// 工具函数 function toKebabCase(str: string): string { return str.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase(); } function generateImports(components: string[]): string { return components .map( name => `import ${name} from '@baidu/cosmic/${toKebabCase(name)}';` ) .join('\n'); } function generateComponentRegistrations(components: string[]): string { const registrations = components .map(name => ` 'cos-${toKebabCase(name)}': ${name}`) .join(',\n'); return `static components = {\n${registrations}\n };`; }
- src/tools/san/config/index.ts:1-106 (helper)Configuration constants: COMPONENT_TEMPLATE, STYLE_TEMPLATE for code generation, and COSMIC_COMPONENTS list used by the 'san' tool.// 组件模板配置 export const COMPONENT_TEMPLATE = `import { defineComponent } from 'san'; import Button from '@baidu/cosmic/button'; import './index.less'; // 导入cosmic组件 {{imports}} interface Props { // 在这里定义组件的props类型 } interface State { // 在这里定义组件的state类型 } export default defineComponent({ template: /* html */ \` <div class=""> <!-- Button组件使用示例 --> <cos-button type="primary" on-click="handleClick">点击按钮</cos-button> <!-- 在这里编写组件模板 --> </div> \`, components: { 'cos-button': Button, {{components}} }, initData(): State { return { // 初始化组件状态 }; }, handleClick(): void { // 按钮点击处理 console.log('按钮被点击'); }, // 在这里添加组件方法 });` export const STYLE_TEMPLATE = ` .{{componentName}} { /* 在这里编写组件样式 */ display: flex; justify-content: space-between; padding: 16px; :global(.cos-button) { // cosmic样式覆盖 } }`; // Cosmic组件列表 export const COSMIC_COMPONENTS = [ 'Avatar', 'AvatarGroup', 'Badge', 'Button', 'ImageUploader', 'Drawer', 'Dialog', 'Empty', 'Fold', 'FoldSwitch', 'Icon', 'Image', 'Input', 'Loading', 'MoreLink', 'Popover', 'Rank', 'RichVideoPlayer', 'Score', 'Swiper', 'SwiperItem', 'Switcher', 'Tag', 'Textarea', 'Toast', 'Tabs', 'Tab', 'TabPane', 'AudioPlayer', 'Tooltip', 'Vote', 'Checkbox', 'CheckboxGroup', 'Radio', 'RadioGroup', 'Select', 'Cascader', 'Table', 'Price', 'Accordion', 'AccordionPanel', 'Calendar', 'DatePicker', 'Timeline', 'TimelineItem', 'CitySelector', 'Pagination', 'TimePicker', 'PickerViewColumn', 'PickerView', 'DateTimePicker', ] as const;