组件化开发是目前前端开发中十分重要的一项技能,无论是 Vue, react 还是小程序对于组件化开发都有很好的支持,要想掌握好组件化开发,组件之间的通信是无法绕过的话题,最近技术栈从 Vue 转向了 react + 小程序,便总结了一下在进行 react 和小程序开发时,组件之间是如何通信的。
组件之间的通信一般有三种,一种是父组件向子组件通信,一种是子组件向父组件通信,还有一种是兄弟组件之间通信。
首先我们看下 react 和小程序是如何实现父子组件间通信的:
react
子组件
// NiuComp.jsx
import React, { Component } from "react";
import PropTypes from "prop-types";
class NiuComp extends Component {
static propTypes = {
name: PropTypes.string, // number bool array func object isRequired
changeName: PropTypes.func,
}
changeName = () => {
this.props.changeName({name: 'jack'})
}
render() {
return (
<button onClick={this.changeName}>{this.props.name}</button>
);
}
}
export default NiuComp;
父组件
// Home.jsx
import React, { Component } from "react";
import NiuComp from '../../components/NiuComp';
class Result extends Component {
state = {
name: 'iwen'
}
changeName = (data) => {
this.setState(data)
}
render() {
return <div>
<NiuComp name={this.state.name} changeName={this.changeName}/>
</div>;
}
}
export default Result;
从例子中我们可以看到父组件是通过在子组件上添加一个自定义属性比如 name={this.state.name}
来向子组件传值的,在子组件中通过 this.props.name
可以获取父组件传递的值。而子组件是通过父组件传递的函数 changeName 来修改父组件中的值。
接下来我们看下小程序是如何处理的
小程序
子组件
// wxml
<button bindtap='changeName'>{{name}}</button>
// js
Component({
properties: {
name: String
},
methods: {
changeName() {
this.triggerEvent('changeName', {name: 'jack'});
}
}
})
// json
{
"component": true
}
父组件
// wxml
<niu name='{{name}}' bindchangeName='changeName'/>
// js
Page({
data: {
name: 'iwen'
},
changeName(val) {
console.log(val.detail)
}
})
// json
{
"usingComponents": {
"niu": "./niu/index"
}
}
小程序中父组件向子组件传值的方式和 react 十分相似,但是子组件向父组件传值就不太一样了,并没有采用回调函数的方式而是采用了自定义事件的方式实现,在子组件中自定义一个事件,在父组件中监听这个自定义事件。
最后还有一个常用的通信就是兄弟组件之间的通信,对于兄弟组件的通信一般都是采用事件 bus 实现,本质上还是自定义事件
const EventEmitter = require('events');
class Bus extends EventEmitter { }
export default new Bus()
// 组件 A
import bus from './bus'
bus.on('run', (name) => {
console.log(name, 'run')
})
// 组件B
import bus from './bus'
bus.emit('run', 'iwen')