New:Introducing Socket Scanning for VS Code Marketplace Extensions.Learn more →
Get Started

@baihuiru/trans-components

Package Overview
Dependencies
Maintainers
1
Versions
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@baihuiru/trans-components

Transform React and Vue components to Web Components for cross-framework sharing

latest
Source
npmnpm
Version
1.0.0
Version published
Maintainers
1
Created
Source

@trans/components

一个强大的组件转换库,支持将 React 和 Vue 组件转换为 Web Components,实现真正的跨框架组件共享。

✨ 特性

  • 🚀 跨框架支持: 支持 React 和 Vue 组件转换
  • 🎯 零配置: 开箱即用,简单易用
  • 🔧 TypeScript 支持: 完整的类型定义
  • 🎨 样式隔离: 支持 Shadow DOM 样式隔离
  • 📦 体积小巧: 基于 Lit 构建,体积轻量
  • 🔄 双向通信: 支持 props 传递和事件监听
  • 🛠 插件化架构: 支持自定义转换器

📦 安装

npm install @trans/components

Peer Dependencies

# 如果使用 React 组件转换
npm install react react-dom

# 如果使用 Vue 组件转换  
npm install vue

🚀 快速开始

React 组件转换

import React from 'react';
import { transformAndRegisterReactComponent } from '@trans/components';

// 你的 React 组件
const MyButton = ({ text, onClick }) => (
  <button onClick={onClick}>{text}</button>
);

// 转换配置
const config = {
  tagName: 'my-button',
  props: {
    text: 'Click me'
  },
  events: ['click']
};

// 转换并注册为 Web Component
transformAndRegisterReactComponent(MyButton, config);

Vue 组件转换

import { defineComponent } from 'vue';
import { transformAndRegisterVueComponent } from '@trans/components';

// 你的 Vue 组件
const MyCounter = defineComponent({
  props: ['initialValue'],
  data() {
    return { count: this.initialValue || 0 };
  },
  template: '<div>{{ count }}</div>'
});

// 转换配置
const config = {
  tagName: 'my-counter',
  props: {
    initialValue: 0
  },
  events: ['change']
};

// 转换并注册为 Web Component
transformAndRegisterVueComponent(MyCounter, config);

在 HTML 中使用

<!DOCTYPE html>
<html>
<head>
  <script type="module" src="your-components.js"></script>
</head>
<body>
  <!-- 使用转换后的 Web Components -->
  <my-button text="Hello World"></my-button>
  <my-counter initial-value="10"></my-counter>
  
  <script>
    // 监听事件
    document.querySelector('my-button').addEventListener('click', () => {
      console.log('Button clicked!');
    });
    
    document.querySelector('my-counter').addEventListener('change', (e) => {
      console.log('Counter changed:', e.detail);
    });
  </script>
</body>
</html>

📚 API 文档

统一 API

transformComponent(component, config, framework)

转换组件为 Web Component 类。

import { transformComponent } from '@trans/components';

const WebComponent = transformComponent(MyComponent, config, 'react');
customElements.define('my-component', WebComponent);

transformAndRegister(component, config, framework)

转换组件并自动注册为 Web Component。

import { transformAndRegister } from '@trans/components';

transformAndRegister(MyComponent, config, 'react');

autoRegister(components)

批量转换和注册多个组件。

import { autoRegister } from '@trans/components';

autoRegister([
  { component: ReactButton, config: buttonConfig, framework: 'react' },
  { component: VueCounter, config: counterConfig, framework: 'vue' }
]);

React 专用 API

import { 
  transformReactComponent,
  transformAndRegisterReactComponent 
} from '@trans/components';

// 仅转换
const WebComponent = transformReactComponent(MyComponent, config);

// 转换并注册
transformAndRegisterReactComponent(MyComponent, config);

Vue 专用 API

import { 
  transformVueComponent,
  transformAndRegisterVueComponent 
} from '@trans/components';

// 仅转换
const WebComponent = transformVueComponent(MyComponent, config);

// 转换并注册
transformAndRegisterVueComponent(MyComponent, config);

⚙️ 配置选项

ComponentConfig

interface ComponentConfig {
  tagName: string;           // Web Component 标签名 (必须包含连字符)
  props?: Record<string, any>;    // 默认属性值
  events?: string[];              // 支持的事件列表
  styles?: string;               // CSS 样式
  shadow?: boolean;              // 是否使用 Shadow DOM (默认: true)
  attributes?: Record<string, string>; // HTML 属性映射
}

完整示例

const config = {
  tagName: 'my-component',
  props: {
    title: 'Default Title',
    count: 0,
    disabled: false
  },
  events: ['click', 'change', 'custom-event'],
  styles: `
    :host {
      display: block;
      padding: 16px;
    }
    
    .container {
      border: 1px solid #ccc;
      border-radius: 4px;
    }
  `,
  shadow: true,
  attributes: {
    'aria-label': 'My Component'
  }
};

🎯 在不同框架中使用

在 React 中使用

function App() {
  const handleClick = () => {
    console.log('Clicked!');
  };

  return (
    <div>
      <my-button text="React App" onCustomEvent={handleClick} />
    </div>
  );
}

在 Vue 中使用

<template>
  <div>
    <my-button text="Vue App" @custom-event="handleClick" />
  </div>
</template>

<script>
export default {
  methods: {
    handleClick() {
      console.log('Clicked!');
    }
  }
}
</script>

在 Angular 中使用

// app.module.ts
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';

@NgModule({
  schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class AppModule {}
<!-- app.component.html -->
<my-button text="Angular App" (customEvent)="handleClick()"></my-button>

🔧 高级用法

自定义转换器

import { BaseTransformer, ComponentConfig } from '@trans/components';

class CustomTransformer extends BaseTransformer {
  name = 'custom-transformer';
  framework = 'custom' as const;
  
  transform(component: any, config: ComponentConfig) {
    // 自定义转换逻辑
    return this.createWebComponent(component, config, (element) => {
      // 自定义渲染逻辑
    });
  }
}

// 注册自定义转换器
import { getRegistry } from '@trans/components';
const registry = getRegistry();
registry.register(new CustomTransformer());

动态属性更新

const component = document.querySelector('my-component');

// 更新属性
component.title = 'New Title';
component.count = 10;

// 监听属性变化
const observer = new MutationObserver((mutations) => {
  mutations.forEach((mutation) => {
    if (mutation.type === 'attributes') {
      console.log('Attribute changed:', mutation.attributeName);
    }
  });
});

observer.observe(component, { attributes: true });

📋 最佳实践

1. 命名规范

  • Web Component 标签名必须包含连字符
  • 建议使用命名空间前缀,如 my-app-button
  • 事件名使用 kebab-case,如 custom-event

2. 样式管理

const config = {
  tagName: 'my-component',
  styles: `
    /* 使用 :host 选择器设置组件容器样式 */
    :host {
      display: block;
      --primary-color: #1890ff;
    }
    
    /* 使用 CSS 变量实现主题定制 */
    .button {
      background: var(--primary-color);
    }
    
    /* 响应式设计 */
    @media (max-width: 768px) {
      :host {
        padding: 8px;
      }
    }
  `
};

3. 事件处理

// 组件内部触发事件
const handleClick = () => {
  // 触发自定义事件
  element.dispatchEvent(new CustomEvent('custom-click', {
    detail: { value: 'some data' },
    bubbles: true,
    composed: true  // 允许事件穿越 Shadow DOM 边界
  }));
};

4. 性能优化

  • 使用 shadow: false 如果不需要样式隔离
  • 避免在 props 中传递大对象
  • 合理使用事件冒泡

🔍 故障排除

常见问题

  • 组件不显示

    • 检查是否正确导入和注册
    • 确认标签名包含连字符
    • 检查浏览器控制台错误
  • 样式不生效

    • 确认使用了正确的 CSS 选择器
    • 检查 Shadow DOM 设置
    • 使用 :host 选择器
  • 事件不触发

    • 确认事件名在 config.events 中
    • 检查事件监听器绑定
    • 确认使用了 composed: true
  • TypeScript 类型错误

    • 确保安装了对应的 @types 包
    • 检查 tsconfig.json 配置

🤝 贡献指南

欢迎贡献代码!请阅读 CONTRIBUTING.md 了解详细信息。

📄 许可证

MIT License - 详见 LICENSE 文件。

🙏 致谢

  • Lit - 高性能 Web Components 库
  • React - 用户界面构建库
  • Vue - 渐进式 JavaScript 框架

Keywords

web-components

FAQs

Package last updated on 28 Aug 2025

Related posts