今天主要学习ref方法去调用子组件的方法, react hook和vue 单文件都使用到
喜欢的可以点赞
React
useRef 仅能用在 FunctionComponent,createRef 仅能用在 ClassComponent。
使用useRef
子组件(Child.tsx)
# Child.tsx
export interface ChildProps {
count: number;
setCount: (params: ChildProps["count"]) => void;
}
const Child = (_props: any, ref: any) => {
let [count, setCount] = useState(0);
useImperativeHandle(ref, () => ({
count,
setCount,
}));
return (
<div>
<p>{count}</p>
</div>
);
};
export default Child;
# or
export interface ChildProps {
count: number;
setCount: (params: ChildProps["count"]) => void;
}
interface refInterface {
cRef: React.MutableRefObject<ChildProps | undefined>;
}
const Child: React.FC<refInterface> = (props) => {
const { cRef } = props;
let [count, setCount] = useState(0);
useImperativeHandle(cRef, () => ({
count,
setCount,
}));
return (
<div>
<p>{count}</p>
</div>
);
};
export default Child;
父组件(Parent.tsx)
# Parent.tsx
function Parent() {
const childRef = useRef<ChildProps>();
const updateChildState = () => {
// changeVal就是子组件暴露给父组件的方法
childRef.current?.setCount(childRef.current?.count + 1);
};
return (
<div>
<Child ref={childRef}></Child>
<button onClick={updateChildState}>按钮</button>
</div>
);
}
createRef
子组件(Child.tsx)
import React, { useState } from "react";
interface ChildInterface {
count: number;
}
class Child extends React.Component<unknown, ChildInterface> {
constructor(props: React.FC) {
super(props);
this.state = {
count: 0,
};
}
render() {
return (
<div>
<p>{this.state.count}</p>
</div>
);
}
setCount = (params: number) => {
this.setState({
count: params,
});
};
}
export default Child;
父组件(Parent.tsx)
import Child from "./Child";
class Parent extends React.Component {
childRef: RefObject<Child>;
// childRef: LegacyRef<Child> | undefined;
constructor(props: React.FC) {
super(props);
this.childRef = createRef();
}
render() {
return (
<div>
<Child ref={this.childRef}></Child>
<button onClick={this.updateChildCount}>按钮</button>
</div>
);
}
updateChildCount = () => {
let { setCount, state } = this.childRef.current as Child;
setCount(state.count + 1);
};
}
export default Parent;
Vue3
父组件兼容二个写法
父组件(Parent.vue)
# Parent.vue
<template>
<Child ref="childRef"></Child>
<button @click="onClick">按钮</button>
</template>
<script setup lang="ts">
import { ref } from "vue";
import Child from "./Child.vue";
const childRef = ref<InstanceType<typeof Child>>();
const onClick = () => {
console.log(childRef.value);
childRef.value?.setCount(childRef.value?.count + 1);
childRef.value?.setCount2(childRef.value?.count2 + 1);
};
</script>
常规写法
子组件(Child.vue)
# Child.vue
<template>
<div>
<p>count: {{ count }}</p>
<p>count2: {{ count2 }}</p>
</div>
</template>
<script lang="ts">
import { ref, defineComponent, Ref } from "vue";
export default defineComponent({
data() {
return {
count2: 2,
};
},
methods: {
setCount2(param: number) {
this.count2 = param;
},
},
setup() {
let count = ref(0);
function setCount(param: number) {
count.value = param;
}
return {
count,
setCount,
};
},
});
</script>
单文件写法(setup)
<template>
<div>
<p>{{ count }}</p>
</div>
</template>
<script setup lang="ts">
import { ref } from "vue";
const count = ref(0);
function setCount(param: number) {
count.value = param;
}
defineExpose({
count,
setCount,
});
</script>
<style scoped></style>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。