1.实现功能(ts)
0.基础属性使用
1.组件直接的通信
2.useState 动态修改值
3.循环遍历功能
4.实现类型vue 的 watch ,filter,computed 属性功能
5.实现类似vue2的生命周期
5.类型vue v-if功能的实现
2.文件结构图

3.具体代码
interface.ts
import "./index.less";
import { message } from "antd";
import { useState, useEffect, useRef } from "react";
import { UserInfo } from "./interface";
import UserAge from "./components/UserAge"
const UseComponent = () => {
let [user, setUser] = useState<UserInfo>({ name: "张三", age: 5 });
const [messageApi, contextHolder] = message.useMessage();
let [show, setShow] = useState<boolean>(false);
// 循环遍历
let [userList] = useState<UserInfo[]>([
{ id: 1, name: "张三", age: 5 },
{ id: 2, name: "李四", age: 10 },
{ id: 3, name: "王五", age: 15 }
]);
const updateShow = () => {
setShow(!show)
}
const updateAge = (updateAge: number, type: string = "add") => {
let ageTemp: number = user.age;
if (type === "add") {
ageTemp = ageTemp + updateAge;
} else if (type === "reduce") {
ageTemp = ageTemp - updateAge;
}
if (ageTemp < 0) {
messageApi.error("年龄不能小于0");
ageTemp = 0;
} else if (ageTemp > 100) {
messageApi.error("年龄不能大于100");
ageTemp = 100;
}
setUser(user => ({
...user,
age: ageTemp
}));
};
const updateChild = (age: number) => {
updateAge(age)
}
// 类型vue 的生命周期
// Vue2 生命周期 | React 实现
//---------------------------------------
// beforeCreate => 无直接等价(可用 useRef 模拟)
// created => useEffect 空依赖
// beforeMount => useLayoutEffect 空依赖
// mounted => useEffect 空依赖
// beforeUpdate => useLayoutEffect 无依赖
// updated => useEffect 无依赖
// beforeDestroy => useEffect 返回清理函数
// destroyed => useEffect 返回清理函数
const UseComponent = () => {
// beforeCreate 阶段(组件初始化前)
const initializedRef = useRef<boolean>(false);
if (!initializedRef.current) {
console.log("beforeCreate - 类似 Vue 的 beforeCreate");
initializedRef.current = true;
}
// created 阶段(组件初始化)
useEffect(() => {
console.log("created - 类似 Vue 的 created");
}, []);
// mounted 阶段(DOM 挂载完成)
useEffect(() => {
console.log("mounted - 类似 Vue 的 mounted");
}, []);
// updated 阶段(数据更新)
useEffect(() => {
console.log("updated - 类似 Vue 的 updated");
});
// beforeDestroy 阶段(组件卸载前)
useEffect(() => {
return () => {
console.log("beforeDestroy - 类似 Vue 的 beforeDestroy");
};
}, []);
}
UseComponent()
return (
<>
{contextHolder}
<div className="card content-box">
<div>姓名:{user.name}</div>
<div>年龄:{user.age}</div>
<div className="flex-btn">
<button className="add-btn" onClick={() => updateAge(1)}>年龄+1</button>
<button className="add-btn" onClick={() => updateAge(1, "reduce")}>年龄-1</button>
<button className="add-btn" onClick={() => updateShow()}>{!show ? "显示" : '隐藏'}</button>
</div>
<div className="child">
<div>我是子组件</div>
{show && <UserAge user={user} updateChild={updateChild} />}
</div>
<div>
{userList.map((item, index) => {
return (
<div key={index}>
<div>姓名:{item.name}</div>
<div>年龄:{item.age}</div>
<div>------------------</div>
</div>
)
})}
</div>
</div>
</>
);
};
export default UseComponent;
interface.ts
// 定义属性 ?代表可填可不填
export interface UserInfo {
id?: number;
name: string;
age: number;
}
UserAge.tsx
import React from "react";
import { UserInfo } from "../interface";
interface Props {
user: UserInfo;
updateChild: (num: number) => void;
}
const UserAge: React.FC<Props> = (props) => {
//获取父组件的参数
// 类似 vue 的 watch
React.useEffect(() => {
console.log("子组件渲染", props.user);
}, [props.user]);
// 类似 vue 的 computed
const ageStatus: string = React.useMemo(() => {
return props.user.age > 20 ? '中年' : '少年'
}, [props.user.age]);
// 类似vue 的 filter 也可以使用自定义hook的方式实现
const ageFilter = (age: number) => {
return age + "岁"
}
// 向父组件传递参数
const updateFan = () => {
props.updateChild(5);
};
return (
<>
<div>我是子组件的age: {ageFilter(props.user.age)} {ageStatus}</div>
<button onClick={updateFan}>子组件控制父组件</button>
</>
);
}
export default UserAge;