You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否在Vue.js中使用React.js组件及包、反之是否也可实现?

无需Vuera在Vue项目中复用React组件的实现方法

目前有两种成熟的无第三方跨框架库的实现方案,适配新版React、Vue3/Vue2都可以正常使用:

方案1:手动编写Vue包装组件(最灵活,无额外依赖)

核心逻辑是在Vue组件的生命周期中调用ReactDOM的能力挂载、卸载React组件,同时处理双向数据同步和事件透传,操作步骤如下:

  • 首先在Vue项目中安装React运行时依赖:
    # 核心依赖
    npm install react react-dom
    # TS项目额外安装类型定义
    npm install @types/react @types/react-dom -D
    
  • 编写Vue包装组件,示例如下(以Vue3+React18为例):
    <template>
      <!-- React组件的挂载容器 -->
      <div ref="reactContainer"></div>
    </template>
    
    <script setup>
    import { ref, onMounted, onUnmounted, watch } from 'vue'
    import React from 'react'
    import { createRoot } from 'react-dom/client'
    // 导入你要复用的旧React组件
    import OldReactButton from './components/OldReactButton.jsx'
    
    const reactContainer = ref(null)
    let reactRoot = null
    
    // 组件挂载时初始化React实例
    onMounted(() => {
      reactRoot = createRoot(reactContainer.value)
      renderReactComp()
    })
    
    // 渲染React组件,同步Vue侧的props和事件
    const renderReactComp = () => {
      reactRoot.render(
        <OldReactButton 
          // 透传Vue侧传入的属性
          btnText="提交"
          type="primary"
          // 把React组件触发的事件转为Vue自定义事件向外透传
          onBtnClick={handleReactEvent}
        />
      )
    }
    
    const handleReactEvent = (eventParams) => {
      // 此处可以处理React事件返回的参数,按需传递给Vue侧逻辑
      console.log('React组件触发事件', eventParams)
    }
    
    // 如果需要支持响应式属性同步,监听对应props变化,重新调用renderReactComp即可,React的diff算法会自动处理更新,不会有性能问题
    
    // Vue组件卸载时销毁React实例,避免内存泄漏
    onUnmounted(() => {
      reactRoot.unmount()
    })
    </script>
    

如果是Vue2项目,只需要把生命周期钩子对应改为mounted、beforeDestroy,React渲染方法替换为对应版本的ReactDOM.render即可。

方案2:基于Web Components做通用中间层

如果有大量React组件需要复用,或者后续还要适配其他框架,可以把React组件编译为标准Web Components(自定义元素),Vue对原生自定义元素有原生支持,不需要额外适配:

  • 先把React组件封装为自定义元素,示例代码如下:
    // react-button-wc.jsx
    import React from 'react'
    import { createRoot } from 'react-dom/client'
    import OldReactButton from './OldReactButton.jsx'
    
    class ReactButton extends HTMLElement {
      connectedCallback() {
        this.root = createRoot(this)
        this.render()
      }
    
      // 声明需要监听的属性,属性变化时自动触发更新
      static get observedAttributes() {
        return ['btn-text', 'disabled']
      }
    
      attributeChangedCallback() {
        this.render()
      }
    
      render() {
        const btnText = this.getAttribute('btn-text')
        const disabled = this.hasAttribute('disabled')
        this.root.render(
          <OldReactButton 
            btnText={btnText}
            disabled={disabled}
            onBtnClick={(e) => {
              // 抛出原生自定义事件,Vue侧可以直接监听
              this.dispatchEvent(new CustomEvent('btn-click', { detail: e }))
            }}
          />
        )
      }
    
      disconnectedCallback() {
        this.root.unmount()
      }
    }
    
    // 注册自定义元素
    customElements.define('react-button', ReactButton)
    
  • 在Vue项目中引入上述文件后,直接像原生HTML标签一样使用即可:
    <template>
      <react-button 
        btn-text="提交"
        @btn-click="handleClick"
      />
    </template>
    

注意事项

  • 如果React组件依赖React生态的上下文(比如Redux、React Query等),需要在包装层加上对应的Provider组件,保证上下文正常传递
  • 跨框架通信尽量传递基础类型参数,避免直接传递复杂响应式对象,减少两边响应式系统的冲突
  • 如果是SSR项目,需要给跨框架的包装组件加上客户端渲染标记,避免服务端渲染报错

内容的提问来源于stack exchange,提问作者Yash Sonalia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 15:45:10