Vue调用React组件的那些事

举报
敛裳宵逝 发表于 2021/08/19 16:26:32 2021/08/19
【摘要】 Vue调用React组件的环境配置;Vue父组件与React子组件互相传递参数;Vue父组件调用React子组件的方法;

        最近碰到一个需求,需要将一个开源的React项目集成到Vue项目中。记录一下碰到的几个关键点:

  1. 环境配置
  2. Vue父组件与React子组件互相传递参数
  3. 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

        为了解决ReactVue的语法差异问题,需要安装以下依赖(注意前面三个依赖的版本需匹配):

"@babel/plugin-transform-react-jsx": "^x.x.x",
"@babel/preset-env": "^x.x.x",
"@babel/preset-react": "^x.x.x",
"vuera": "^x.x.x"

        为了解决VueReact关于jsx的语法冲突问题,需要修改Vue项目下的babel.config.js配置文件。首先关闭vuejsx识别,再添加reactenv,最后添加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中需要从后端获取一个配置文件,获取成功后设置标志变量isConfigLoadedTrue,并且将配置文件中的关键字段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保持一致,用”:”绑定。但是传递参数时,必须使用”:”才行。以上。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。