背景: 在 React 工程中嵌入 Vue 工程的指定模块代码,具体要求为,切换 React 路由时页面不整体刷新,仅内容区渲染对应的 Vue 模块, 或者Vue工程中嵌入React模块;
现行技术下,已经存在诸如qiankun.js等微前端方案,样式隔离,沙箱机制等;随着Vue3已经支持导出Web Components标准API,考虑长期影响和技术演进,是否能尽可能快且低成本的的完成以上需求?
有没有大佬实际改造的案例可以分享? Shadow DOM, 事件穿透,样式方案等?
背景: 在 React 工程中嵌入 Vue 工程的指定模块代码,具体要求为,切换 React 路由时页面不整体刷新,仅内容区渲染对应的 Vue 模块, 或者Vue工程中嵌入React模块;
现行技术下,已经存在诸如qiankun.js等微前端方案,样式隔离,沙箱机制等;随着Vue3已经支持导出Web Components标准API,考虑长期影响和技术演进,是否能尽可能快且低成本的的完成以上需求?
有没有大佬实际改造的案例可以分享? Shadow DOM, 事件穿透,样式方案等?
以下是针对跨框架(React与Vue)模块级集成的技术方案与案例,结合低成本、快速落地的核心需求,提供两种主流方案及实践建议:
适用场景:将 Vue 组件嵌入 React 工程
优势:Vue3 原生支持导出标准 Web Components,无需额外微前端框架,轻量且兼容性强。
步骤与代码示例:
Vue 组件改造
使用 Vue 的 defineCustomElement 将组件转换为 Web Components:
// vue-component.ce.vue
import { defineCustomElement } from 'vue'
export default defineCustomElement({
props: ['title'],
template: `<div>{{ title }}</div>`
})
// 注册为全局自定义元素
customElements.define('vue-widget', defineCustomElement(VueComponent))React 中直接使用
在 React 路由组件中直接引入自定义元素(无需额外库):
// ReactPage.jsx
export default function ReactPage() {
return (
<div>
<h1>React 容器</h1>
{/* 直接使用 Web Components 标签 */}
<vue-widget title="嵌入的Vue组件"></vue-widget>
</div>
)
}关键问题解决:
样式隔离:
Web Components 默认使用 Shadow DOM 隔离样式,但需注意:
::part() 选择器或 :host 定制scoped 或 CSS Modules事件通信:
使用 Custom Events 实现跨框架通信:
// Vue 组件内部
this.dispatchEvent(new CustomEvent('vue-event', { detail: data }))
// React 中监听
const ref = useRef()
useEffect(() => {
ref.current.addEventListener('vue-event', (e) => console.log(e.detail))
}, []):user-name="xxx")适用场景:复杂模块、需独立运行时环境(如 Vue 组件依赖全局状态)
优势:沙箱隔离完善,支持多技术栈共存,适合大型应用。
改造步骤:
React 主应用配置(qiankun)
// main-react-app.js
import { registerMicroApps, start } from 'qiankun'
registerMicroApps([
{
name: 'vue-module',
entry: '//localhost:7100', // Vue子应用地址
container: '#vue-container', // 挂载节点
activeRule: '/vue-module' // 路由规则
}
])
start()Vue 子应用改造
导出生命周期钩子:
// vue-sub-app.js
import Vue from 'vue'
export async function bootstrap() { /* ... */ }
export async function mount(props) {
new Vue({ render: h => h(App) }).$mount(props.container.querySelector('#app'))
}
export async function unmount() { /* ... */ }关键问题解决:
shadowDOM 或 scopedCSS 模式。props 传递路由信息给子应用。qiankun 的 initGlobalState 或自定义事件总线。某电商平台中台系统
| 方案 | 成本 | 性能 | 适用场景 | 风险点 |
|---|---|---|---|---|
| Web Components | 低 | ★★★★ | 简单组件嵌入、技术栈较新 | 浏览器兼容性(IE除外) |
| Qiankun 微前端 | 中 | ★★★☆ | 复杂应用、需独立沙箱环境 | 主应用改造复杂度略高 |
推荐路径:
initGlobalState(qiankun)改造关键点:
scopedSlots(Web Components 不支持)window.Vue)避免重复加载最新进展:Vue 3.4+ 已优化 Web Components 的 Props 类型检查与事件派发,可直接传递复杂对象。可参考 Vue 官方文档 - Web Components 集成。
11 回答1.2k 阅读
3 回答853 阅读
4 回答526 阅读✓ 已解决
1 回答851 阅读✓ 已解决
1 回答1.1k 阅读
2 回答767 阅读
2 回答612 阅读
尝试使用web components进行融合测试,具体实践整理成文章放在个人主页了:
https://segmentfault.com/a/1190000047578188