Open yinxin630 opened 5 years ago
是不是看标题就感觉很蛋疼?
最近项目在基于 react 重构, 但是依赖的一个公共业务组件是 vue 的, 并且暂时没有使用 react 重构的计划, 但是总不能一直等下去, 遂尝试在 react 里渲染 vue 组件
需要借助 vuera(https://github.com/akxcv/vuera) 来做这个事情
同时, webpack里需要同时配置 react 和 vue 的 loader
首先, 写一个典型的 vue 组件
// Module.vue <template> <div> <span>click times: {{count}}</span> <br /> <button @click="handleClick">+1s</button> </div> </template> <script> export default { name: "Module", data() { return { count: 0 } }, methods: { handleClick() { this.count++; } } } </script>
然后, 在 react 里面渲染 vue 组件
// index.tsx import React from 'react'; import { render } from 'react-dom'; import { VueWrapper } from 'vuera'; import Module from './Module.vue'; render( <div> <h2>下面是vue组件</h2> <VueWrapper component={Module} /> </div>, document.getElementById('app'), );
渲染效果:
react 里就像正常 react 组件一样传参即可
// index.tsx <VueWrapper component={Module} msg="message pass by props" />
vue 里也是和正常 vue 组件一样, 定义 props
// Module.vue <template> <div> <h3>{{msg}}</h3> ... </div> </template> <script> export default { ... props: { msg: { type: String, } }, ... } </script>
在 vue 里面可以调用 this.$emit('xxx') 抛出事件
this.$emit('xxx')
但是, react 组件里, 不能直接用 @xxx 或者 v-on:xxx 绑定事件, 但是可以通过 props 传递 function, 在 vue 组件里调用 props function
@xxx
v-on:xxx
vue 组件对外抛出事件
// Module.vue <script> export default { ... props: { ... onCountChange: { type: Function } }, methods: { handleClick() { this.count++; this.onCountChange(this.count); } } } </script>
如果 vue 组件不受自己控制, 不能修改源码的话, 也可以自己封装一层, 将 props function 转为 @xxx
使用 this.$emit() 的 vue 组件
this.$emit()
// Module.vue <script> export default { ... methods: { handleClick() { this.count++; this.$emit('count-change', this.count); } } } </script>
创建中间适配层组件 MoudleWrapper
MoudleWrapper
// ModuleWrapper.vue <template> <div> <Module :msg="msg" @count-change="onCountChange"></Module> </div> </template> <script> import Module from './Module.vue'; export default { name: "ModuleWrapper", components: { Module }, props: { msg: { type: String, }, onCountChange: { type: Function } }, } </script>
修改入口文件, 改为渲染 MoudleWrapper 组件
// index.tsx import React from 'react'; import { render } from 'react-dom'; import { VueWrapper } from 'vuera'; import MoudleWrapper from './MoudleWrapper.vue'; render( <div> <h2>下面是vue组件</h2> <VueWrapper component={MoudleWrapper} msg="message pass by props" onCountChange={console.log} /> </div>, document.getElementById('app'), );
使用 vue 组件, 会把完整的 vue.js 打包进去
如果该 vue 组件并不是初始状态就需要展示的话, 可以做按需加载打成一个单独的 chunk, 使其不影响页面初始渲染时间
下面是一个按需加载的例子, 新增 App 组件来做动态展示和按需加载的逻辑
// App.tsx import React, { useState, useEffect } from 'react'; import { VueWrapper } from 'vuera'; let MoudleWrapper: any = null; export default function App() { const [showVueModule, toggleVueModule] = useState(false); function showHideVueModule() { if (MoudleWrapper) { toggleVueModule(!showVueModule); } else { import(/* webpackChunkName: "vue-module" */ './MoudleWrapper.vue').then(module => { MoudleWrapper = module.default; toggleVueModule(!showVueModule); }); } } return ( <div> <h2>下面是vue组件</h2> { showVueModule && MoudleWrapper ? <div><VueWrapper component={MoudleWrapper} msg="message pass by props" onCountChange={console.log} /></div> : null } <button onClick={showHideVueModule}>展示/隐藏vue组件</button> </div> ); }
运行效果如下:
我这边 现在是不显示 也不报错 您遇到过这情况么
只能一步步调试看看了
前言
是不是看标题就感觉很蛋疼?
最近项目在基于 react 重构, 但是依赖的一个公共业务组件是 vue 的, 并且暂时没有使用 react 重构的计划, 但是总不能一直等下去, 遂尝试在 react 里渲染 vue 组件
vuera
需要借助 vuera(https://github.com/akxcv/vuera) 来做这个事情
同时, webpack里需要同时配置 react 和 vue 的 loader
首先, 写一个典型的 vue 组件
然后, 在 react 里面渲染 vue 组件
渲染效果:
向 vue 组件传参
react 里就像正常 react 组件一样传参即可
vue 里也是和正常 vue 组件一样, 定义 props
接收 vue 组件抛出的事件
在 vue 里面可以调用
this.$emit('xxx')
抛出事件但是, react 组件里, 不能直接用
@xxx
或者v-on:xxx
绑定事件, 但是可以通过 props 传递 function, 在 vue 组件里调用 props functionvue 组件对外抛出事件
如果 vue 组件不受自己控制, 不能修改源码的话, 也可以自己封装一层, 将 props function 转为 @xxx
使用
this.$emit()
的 vue 组件创建中间适配层组件
MoudleWrapper
修改入口文件, 改为渲染 MoudleWrapper 组件
打包
使用 vue 组件, 会把完整的 vue.js 打包进去
如果该 vue 组件并不是初始状态就需要展示的话, 可以做按需加载打成一个单独的 chunk, 使其不影响页面初始渲染时间
下面是一个按需加载的例子, 新增 App 组件来做动态展示和按需加载的逻辑
运行效果如下: