功能背景
之前在写vue的时候用到一个很好用的东西,比如控制一个dialog的显示隐藏,那么可以由父组件控制它显示,子组件(即这个dialog)自己可以关闭自己,那么他们之间只维护一个visible的状态,就需要响应式的操作。
vue中
子组件
//vue2.x
props:['dialogVisible','desc'],
computed:{
"_dialogVisible":{
get(){
return this.dialogVisible
},
set(val){
this.$emit('update:dialogVisible',val)
}
},
}
//vue3.x
props: {
dialogVisible: {
type: Boolean,
},
},
const _dialogVisible = computed({
get(){
return props.dialogVisible
},
set(val){
emit('update:dialogVisible',false)
}
})
父组件
父组件引入子组件,并双向传值,写法为sync
//vue2.x
<mydialog :dialogVisible.sync="dialogVisibleCropper" :desc="desc"/>
//vue3.x
<mydialog
v-model:dialogVisible="dialogVisibleCropper" />
react中
效果如图
子组件
import { Button } from 'antd';
import React from 'react';
import { useEffect, useState,useRef } from 'react'
import eventBus from '@/utils/eventBus';
const SonComponent = ({ dialogVisible, updateVisible }) => {
const _visible = {
get() {
return dialogVisible;
},
set(val) {
//广播子组件的状态改变
updateVisible && updateVisible(val);
},
};
const ctrlChoosen = (event) => {
_visible.set(event.target.checked);
};
const closeVisible = () => {
_visible.set(false);
};
//这里实现eventBus的监听,监听父组件的传参
useEffect(() => {
eventBus.on('buttonClick', (val) => {
//do some thing
console.log('监听到',val)
});
return () => {
eventBus.off('buttonClick');
};
}, []);
return (
<div>
<Button onClick={closeVisible}>子组件控制关闭</Button>
<br></br>
<input type="checkbox" checked={_visible.get()} onChange={ctrlChoosen} />
<label>子组件状态{_visible.get()?'开':'关'}</label>
</div>
);
};
export default SonComponent;
父组件
//父子组件响应式交互
const [dialogVisible, setDialogVisible] = useState(false);
//订阅子组件的状态改变
const subscribeVisible = (newDialogVisible) => {
// 将逻辑层的状态设置为新的计算属性值
setDialogVisible(newDialogVisible);
};
//然后父组件同时使用监听 监听这个状态 还可以做一些其他的事,当时也可以在上面的subScribe里面做,这里重在使用这个功能
useEffect(() => {
//这是watch或者说是updated
const watchVisible = ()=>{
// console.log(`Visible has changed: ${dialogVisible}`);
if(dialogVisible){
console.log(`Visible has changed: ${dialogVisible}`);
}
}
watchVisible()
}, [dialogVisible]);
<h1>父子组件响应式交互</h1>
<div>
<Button onClick={()=>{setDialogVisible(true)}}>父组件控制打开</Button>
<SonComponent dialogVisible={dialogVisible} updateVisible={subscribeVisible} />
{/* <p>{`dialogVisible state is ${dialogVisible}`}</p> */}
</div>