react中父组件如何直接调用子组件的方法和属性,以及对比vue3.0父组件调用子组件的方法和属性
- react hook
- vue setup
- 父组件
- 子组件
react hook
forwardRef(render)
useImperativeHandle(ref, createHandle, dependencies?)
import {forwardRef,useEffect,useImperativeHandle,useRef,useState,
} from "react";const ChildrenComponents = forwardRef(function ChildrenComponents(props, ref) {//useImperativeHandle类似于vue3.0的defineExpose,把子组件中要暴漏给父组件属性或方法,以对象的方式抛出去useImperativeHandle(ref,() => {return {initList,exposeParamter() {return {defaultTitleRef,};},defaultTitleRef,name,list,};},[]);const defaultTitleRef = "我是子组件";let [name, setName] = useState("工藤新一");let [list, setList] = useState([{name: "工藤新一",sex: "男",},{name: "毛利兰",sex: "女",},]);//初始化function initList() {console.log("[初始化子组件数据]");}function sendMessage() {// 类似于vue3.0的defineEmitsprops.click("点击子组件给父组件传值");}useEffect(() => {console.log("[useEffect-子组件]", props);}, []);return (<><p>我是子组件:{name}</p><br /><span onClick={sendMessage}>点击子组件给父组件传值</span></>);
});function Forward() {const childrenRef = useRef(null);let [title, setTitle] = useState("我想操作子组件的方法和属性");let [defaultName, setDefaultName] = useState("");let [list, setList] = useState([]);function getMessageHandle(params) {console.log("[我接收了子组件的传值]", params);console.log(childrenRef.current.list);}useEffect(() => {console.log("[useEffect-父组件如何直接调用子组件的方法和属性]");childrenRef.current.initList();console.log("", childrenRef.current.exposeParamter().defaultTitleRef);console.log("[name]", childrenRef.current.name);setDefaultName(childrenRef.current.defaultTitleRef);setList(childrenRef.current.list);}, []);return (<><p>forwardRef:我是父组件</p><p>{defaultName}</p>{/* react通过标签的属性传值 */}<ChildrenComponentsref={childrenRef}title={title}click={getMessageHandle}/>{list.map((item, index) => {return (<p key={index}>{item.name}-{item.sex}</p>);})}</>);
}export default Forward;
vue setup
父组件
<template><div>组件</div><button @click="getHandle">ok</button><ChildrenComponent :title="title" :paramsObject="paramsObject" ref="childrenRef" @clickHandle="operateHandle" />{{paramsObject.name}}
</template><script setup>import {onMounted,ref} from "vue";import ChildrenComponent from "../components/children.vue";let title = ref("组件传值");const childrenRef = ref(null)onMounted(() => {childrenRef.value.initFunction();console.log("[父组件]", childrenRef.value.defaultTitle)})let paramsObject = ref({name: "父组件",age: 29,sex: '男'})function getHandle() {}function operateHandle(params) {console.log("[params]", params)paramsObject.value.name = params.name;console.log("[paramsObject]", paramsObject)}
</script><style>
</style>
子组件
<template><div>我还是个孩子</div><h1>{{props.title}}</h1><button @click="btnHandle">点击按钮</button>
</template><script setup>import {defineProps,defineExpose,defineEmits,ref} from "vue";const props = defineProps({title: {type: String,default: () => {return ''}},paramsObject: {type: Object,default: () => {return {}}}});const emits = defineEmits(["clickHandle"]);console.log("[children]", props.paramsObject)function initFunction() {console.log("[初始化]")}function btnHandle() {console.log("[ok]")emits("clickHandle", {name: '毛利兰'})}let defaultTitle = ref("我是子组件")defineExpose({initFunction,defaultTitle})
</script><style lang="scss" scoped>
</style>