Vue调用React组件的那些事
最近碰到一个需求,需要将一个开源的React项目集成到Vue项目中。记录一下碰到的几个关键点:
- 环境配置
- Vue父组件与React子组件互相传递参数
- Vue父组件调用React子组件的方法
开发环境:
"vue": "^2.x.x";"react": "^17.x.x"
- 环境配置
首先确定React项目中核心组件用到的相关依赖项,如react、react-dom、material-ui等等,以具体情况而定,从package.json文件中将这些依赖拷贝到Vue项目的package.json文件中。cmd进入Vue项目目录,运行命令:
npm install
为了解决React和Vue的语法差异问题,需要安装以下依赖(注意前面三个依赖的版本需匹配):
"@babel/plugin-transform-react-jsx": "^x.x.x",
"@babel/preset-env": "^x.x.x",
"@babel/preset-react": "^x.x.x",
"vuera": "^x.x.x"
为了解决Vue与React关于jsx的语法冲突问题,需要修改Vue项目下的babel.config.js配置文件。首先关闭vue的jsx识别,再添加react和env,最后添加plagins部分。具体改动如下:
presets: [
// '@vue/cli-plugin-babel/preset',
['@vue/cli-plugin-babel/preset', {
'jsx': false
}],
['@babel/preset-react'],
['@babel/preset-env']
],
plugins: [
["@babel/plugin-transform-react-jsx"],
["@babel/plugin-syntax-dynamic-import"],
],
- Vue父组件与React子组件互相传递参数
互相传递参数是一个很常用的场景,首先在目标Vue组件中引入React组件。
import ReactComponent from '../../components/model/ ReactComponent.js'
export default {
components: {
"react-component": ReactComponent
},
}
在template标签中使用引入的React组件时,使用Vue组件相同的参数语法,”:”引号标识变量参数,”@”标识函数参数。
先来看看如何把参数从Vue传到React。假设一个应用场景,在React组件中,有一个异步加载的网络请求,请求完成后,将标志变量isResourceLoaded设为True。在Vue中需要从后端获取一个配置文件,获取成功后设置标志变量isConfigLoaded为True,并且将配置文件中的关键字段targetHashCode传到React组件中,只有实现这部分逻辑的主要代码如下:
Vue父组件中:
<react-component :targetHashCode="targetHashCode" :isConfigLoaded="isConfigLoaded"></react-component>
export default {
data() {
return {
targetHashCode: undefined,
isConfigLoaded: false,
}
}
}
React子组件中:
constructor(props) {
this.state = {
isResourceLoaded: false,
}
}
render() {
return (
<Box>
<Component
targetHashCode={this.props.targetHashCode}
initialized={this.state.isResourceLoaded && this.props.isConfigLoaded}
/>
</Box>
)
}
那React传到Vue该如何实现呢?在上面的基础上,我们增加一些信息,假如在React组件中,从子组件的回调函数获得了业务逻辑的运行进度progress,需要在Vue父组件中将progress更新到后端数据库。主要代码如下(以下只写出增加部分):
Vue父组件中:
<react-component @setProgress="setProgress"></react-component>
export default {
methods: {
setProgress: function (progress) {
// 在这里获取progress参数发起网络请求
}
}
}
React子组件中:
constructor(props) {
this.setProgress = (progress) => {
this.props.setProgress(progress)
};
}
// 业务逻辑回调函数
handleProgressUpdate(progressInfo) {
// 将要传递的参数通过上面定义好的接口回传给Vue父组件
this.setProgress(progressInfo.progress);
}
其中要注意的是,在React使用this.props获取Vue传入的参数名和方法名时,需与Vue中调用组件时,传入的参数名与方法名保持一致。回传参数时,使用在constructor中自定义的回传接口名即可。
- Vue父组件调用React子组件的方法
接着上面的情景往下,在React子组件中有若干方法,其中有一个叫stopBackgroundTask,现在要在Vue父组件进行路由跳转时调用这个方法。具体实现如下:
Vue父组件中:
<react-component :onRef="onRef" ></react-component>
export default {
data() {
return {
reactChildRef: undefined,
}
}
methods: {
beforeRouteLeave(to, from, next) {
// 使用React子组件的引用调用子组件的方法
this.reactChildRef.stopBackgroundTask()
next()
},
onRef: function (ref) {
this.reactChildRef = ref
}
}
}
React子组件中:
componentDidMount() {
this.props.onRef(this);
}
细心的话可以发现,同样是传递一个方法的引用,上面我用了”@setProgress”,但是下面却用了”:onRef”,这是为何?其实用”:”和”@”都是可以正常运行的,可以看到在React子组件中获取Vue传入的参数名和方法名时用的都是props。这里我只是保持Vue的语法风格,将方法名用”@”绑定,引用与ref保持一致,用”:”绑定。但是传递参数时,必须使用”:”才行。以上。
- 点赞
- 收藏
- 关注作者
评论(0)