React & Vue的组件通信

组件之间的通信是面试中极为常见的问题,也是在实际工作中会经常遇到的问题,所以今天来总结一下关于组件通信方面的知识点。

父子组件通信

父 -> 子

Vue

  • props: 父组件向子组件传递数据,同时可以限制传递数据的类型。
  • ref: 父组件访问子组件的实例,可以调用子组件的属性和方法。

React

  • props: 父组件向子组件传递数据,也可以是一个方法。

注: 虽然可以通过ref来获取子组件的实例或DOM,但是在实际项目中,并不推荐这样做。React和Vue优化的本质就是通过操作虚拟DOM,来避免操作真实DOM,提高性能。而使用ref违背了这样的初衷。

子 -> 父

Vue

  • $emit('funcName', data): 子组件派发一个事件,父组件监听该事件。
子组件中:
this.$emit('hello', 'helloWorld');
父组件中:
<child @hello="sayHello" />
复制代码

React

  • 调用父组件的函数: 在react中,可以通过props将父组件的函数,传递给子组件,当子组件想要通知父组件的时候,就调用父组件的函数。
// 父组件
<Child hello={this.hello} />

// 子组件
static propsTypes = {
    hello: Proptypes.func
}

render() {
    return {
     <button onClick={this.props.hello}>hello</button>
    }
}
复制代码

兄弟组件通信

Vue

  • 通过共同父辈组件实现。
// 兄弟组件1
this.$parent.$on('hello',handle);
// 兄弟组件2
this.$parent.$emit('hello')
复制代码

React

  • 通过共同父辈组件(状态提升) 兄弟组件A状态改变,通过调用共同父组件的函数,通知父组件。之后父组件再将兄弟组件A的信息通过props传递给兄弟组件B。
// 父组件
 <A setValue={this.setValue}/>
 <B value={this.state.value} />
复制代码

隔代组件通信

祖先 -> 后代

Vue

  • provide/inject:能够实现祖先给后代传值。
// 祖先组件
provide() {
    return {hello: 'hello'}
}
// 后代组件
inject: ['hello']
复制代码

React

  • context 在react16之后的版本,重新定义了context的使用方法。所以在这里,我们就直接介绍新的版本中,如何使用context
// React.createContext 创建Context对象的API
const StatusContext = React.createContext({
    disabled: false
});

// 祖先组件
 <StatusContext.Provider value={{disabled: true}}>
      <Children />
 </StatusContext.Provider>
 
// 后代组件
<StatusContext.Consumer>
        {context => (
          <button disabled={context.disabled}>
            hello
          </button>
        )}
</StatusContext.Consumer>
复制代码

注:

  • Consumer组件的子组件必须是一个函数的形式,通过参数拿到context。
  • 在react的官方文档中,提醒开发者要小心使用Context,但是在高阶组件或者React状态管理中,Context会经常被提及和使用。

后代 -> 祖先

对于后代向祖先之间的通信,其实vue和react采用的方法本质上是一样的,都是子组件一级一级向上通知。不同vue的实现相比于react的要简单的多。

// 后代组件
function dispatch(eventName, data){
    let parent = this.$parent
    while (parent) {
        parent.$emit(eventName,data)
        parent = parent.$parent
    }
}
<button @click="dispatch('hello', 'hello,world')">
    {{ msg }}
</button>

// 祖先组件
this.$on('hello', this.sayHello)
复制代码

任意组件中的通信

Vue

  • 事件总线$Bus
// main.js
Vue.prototype.$bus = new Bus()
// 组件A
this.$bus.$on('hello', handle)
// 组件B
this.$bus.$emit('hello')
复制代码

事件总线的方式虽然可以实现任意组件中的通信,但是在实际开发中,使用的非常少。因为当项目较大时,可能会涉及到很多组件中的通信,使用$bus,会让你的代码非常杂乱。

  • vuex

React

  • mobx
  • redux: 不同与vuex对vue的高度依赖,redux并不依赖于react,但是redux上手比较复杂,所以现在很多公司选择使用mobx。

以上就是React和Vue中常见的组件通信,如果有错误的地方,希望各位大神多多指正。

分类:
阅读
标签: