Skip to main content
Glama

san

Generate Vue.js components with specific features like templates, styles, computed properties, and lifecycle hooks using PascalCase naming. Supports TypeScript and reusable component integration.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
componentNameYes组件名称(使用PascalCase命名规范)
descriptionNo组件的功能描述(可选)
featuresNo需要包含的特性,使用逗号分隔:template-模板, style-样式, computed-计算属性, lifecycle-生命周期, typescript-TypeScript支持。
selectedComponentsNo选择使用的组件列表

Implementation Reference

  • src/index.ts:11-12 (registration)
    Registers the 'san' tool on the MCP server using its schema and execute function.
    // 注册 San 工具 server.tool('san', sanTool.schema, sanTool.execute);
  • Zod schema defining the input parameters for the 'san' tool.
    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('选择使用的组件列表'), };
  • The main handler function for the 'san' tool that generates San.js component code (TypeScript and LESS) using templates and Cosmic UI components based on the provided component name and other parameters.
    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, }; } }
  • Utility helper functions used by the handler to convert names to kebab-case and generate import statements and component registrations for San.js.
    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 };`; }
  • Configuration constants including templates for San component TS/LESS files and the list of available Cosmic UI components 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;

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/PiuQiuPiaQia/mcp-tool'

If you have feedback or need assistance with the MCP directory API, please join our Discord server