父传子
父组件传值给子组件 给子组件标签绑定属性 在子组件内部直接使用props访问绑定数据。
//父组件
state = {
selected: "",
};
render() {
const arr = ["北京", "上海", "深圳"];
const { selected } = this.state;
// 父组件传值给子组件:给子组件标签绑定属性,在子组件内部直接使用props访问绑定数据。
return (
<div className="wrap">
{arr.map((item, index) => (
<button key={index} onClick={() => this.setState({ selected: item })}>
{item}
</button>
))}
<Box
title="hello wrold"
className="test"
style={{ color: "#0ac" }}
value={selected}
></Box>
</div>
);
}
//子组件
constructor(props){
super(props);
// 在构造函数中直接访问props
console.log(props);
}
render() {
return (
<div className={"box " + this.props.className} style={this.props.style}>
<h1>{this.props.value}</h1>
</div>
)
}
componentDidMount(){
// 在其他的函数中,使用this访问props
console.log(this.props);
}
子传父
子组件传值给父组件:先在父组件调用子组件时绑定自定义属性,属性的值为回调函数。当子组件需要传值给父组件时,调用该属性对应的函数。
//父组件
render() {
return (
<div className="wrap">
<Box
onChange={(item) => { //onChange 自定义属性 会在子组件的props上
console.log(123, item);
}}
></Box>
</div>
);
}
//子组件
render() {
const arr = ["北京", "上海", "深圳"];
return (
<div className="box">
{arr.map((item, index) => (
<button
key={index}
onClick={() => {
this.props.onChange(item); //调用props上的自定义属性 将数据传递给父组件 这里为arr遍历出来的每一项
}}
>
{item}
</button>
))}
</div>
);
}
componentDidMount() {
console.log(this.props);
}
兄弟传值
基于发布订阅者模式
1 eventBus
引入vue 不推荐 vue包很大 还不如插件划算
//这里要添加window 解决this指向问题
export default new window.Vue();
//文件中引入
import eventBus from './eventBus/index.js'
render() {
return (
<div className="box">
<h1>one组件</h1>
{"abcd".split("").map((item) => (
<button key={item} onClick={this.btnAction(item)}>
{item}
</button>
))}
</div>
);
}
btnAction = (item) => () => {
// 传值给two组件
eventBus.$emit("send", item);
};
//two组件
componentDidMount() {
// 监听事件
eventBus.$on("send", (value) => {
this.setState({ oneValue: value });
});
}
2 pubsub-js
import PubSub from 'pubsub-js'
//one组件
render() {
return (
<div className="box">
<h1>one组件</h1>
{"abcd".split("").map((item) => (
<button key={item} onClick={this.btnAction(item)}>
{item}
</button>
))}
</div>
);
}
btnAction = (item) => () => {
// 传值给two组件
PubSub.publish('send', item);
};
//two组件
state = {
oneValue: "",
};
render() {
return (
<div className="box">
<h1>two组件</h1>
<p>value: {this.state.oneValue}</p>
</div>
);
}
componentDidMount() {
// 订阅事件
this.token = PubSub.subscribe('send', (message, data)=>{
this.setState({oneValue: data});
})
}
componentWillUnmount(){
// 移除订阅 防止内存泄漏 提升性能
PubSub.unsubscribe(this.token);
}
mitt
// emiter/index.js
import mitt from "mitt";
const emitter = mitt();
export default emitter;
//one组件
import emiter from './emiter/index.js'
render() {
return (
<div className="box">
<h1>one组件</h1>
{"abcd".split("").map((item) => (
<button key={item} onClick={this.btnAction(item)}>
{item}
</button>
))}
</div>
);
}
btnAction = (item) => () => {
// 传值给two组件
emitter.emit('send', item);
};
//two组件
state = {
oneValue: "",
};
render() {
return (
<div className="box">
<h1>two组件</h1>
<p>value: {this.state.oneValue}</p>
</div>
);
}
componentDidMount() {
// 订阅事件
emitter.on('send', this.onSend);
}
onSend = (value)=>{
this.setState({oneValue: value});
};
componentWillUnmount(){
// 移除订阅 防止内存泄露 提升性能
emitter.off('send', this.onSend);
}
还有很多基于发布订阅者模式的插件 值得一试