背景描述
一个动态组件传值的静态展示
是怎么个情况呢,就是在父组件中点击详情会弹出详情弹窗,点击编辑会弹出编辑弹窗,在详情弹窗中点击编辑会弹出编辑弹窗.
(题外话,我的样式使用的是styled-components,组件库用的antd)
事情是这么个事情,他们之间涉及的传值会有以下这些个情况:(我以为我可以画清楚,结果并不...那就借助一下文字的力量吧)
知识了解
在父组件中引入使用子组件
import Details from "./page/details";
import Edit from "./page/edit";
function App() {
return (
<>
//引入详情子组件
<Details />
//引入编辑子组件
<Edit />
</>
);
}
export default App;
子组件使用父组件的属性和方法(流程)
父组件传递
在父组件中的子组件中通过子组件的属性和方法传递给子组件父组件的属性和方法(有点绕哈,不用太理解,看图!!!)
子组件接收
关于上述呢就是,父组件传递visible属性给子组件使用,子组件通过Drawer的open属性引用父组件的visible来控制详情弹窗的打开.
但是,子组价是不能修改父组件的属性和方法的,所以弹窗关闭的时候,通过设置visible=false是不可行的,只能通过调用父组件中设置visible=false(也就是unVisible)的方法来进行关闭
(绕吗?没办法了,饶了也得慢慢看,我尽力了)
以上的这些呢,主要是子组价使用父组件的属性和方法,但实现了父子组件的基本使用(父组件传递变量控制子组件显示,子组件中通过调用方法在父组件中控制弹窗的关闭)
引申(兄弟组件传值)
在详情页点击编辑显示编辑弹窗
在详情页点击时,调用父组件的方法,这个父组件的方法呢设置编辑弹窗的打开,父组件将打开编辑弹窗的这个变量传递给编辑子组件,也就实现了兄弟组件的传值,与上边关闭弹窗调用方法的步骤一样一样式的.
父组件获取子组件的变量
将子组件的变量在父组件中使用(在父组件中定义一个方法,带有形参,同时使用useState同时在父子组件中定义变量,在子组件中设置变量,通过props的方法利用形参传递给父组件)
父组件
//定义变量 --- 通过传递给子组件的的方法设置变量,从而展示变量(相当于子组件的变量的一个储存与展示的容器)
const [numFather, setNumFather] = useState();
//传递给子组件方法获取子组件的变量
const getChildrenVariable = (childrenVariable: any) => {
setNumFather(childrenVariable);
};
<Children getChildrenVariable={getChildrenVariable} />
<h2>子组件传过来的变量---{numFather}</h2>
子组件
function Children(props: any) {
//获取父组件的方法
const { getChildrenVariable } = props;
//定义变量进行传递
const [numChildren, setNumChildren] = useState(199);
//调用方法通过形参传递变量
getChildrenVariable(numChildren);
return <h1>Children</h1>;
}
总结来说,父子组件都需要定义变量,子组价的变量是要传递的变量,父组件的变量用于接收子组件的变量.子组件接受父组件带有形参的方法,将变量作为实参传递给父组件,实现变量由子组件向父组件的传递.
下面上总代码
(使用前要先安装antd和styled-components)
父组件
import { useState } from "react";
import "./App.css";
import Children from "./page/children";
import Details from "./page/details";
import Edit from "./page/edit";
function App() {
//控制详情弹窗的可见与不可见 --- 传递给子组件变量
const [visibleDetails, setVisibleDEtails] = useState(false);
//控制编辑弹窗的可见与不可见 --- 传递给子组件变量
const [visibleEdit, setVisibleEdit] = useState(false);
//控制编辑与详情弹窗的关闭 --- 传递给子组件方法
const unVisible = () => {
setVisibleEdit(false);
setVisibleDEtails(false);
};
//传递子组件方法 --- 通过调用来使编辑弹窗出现
const editCanSee = () => {
setVisibleEdit(true);
};
//定义变量 --- 通过传递给子组件的的方法设置变量,从而展示变量(相当于子组件的变量的一个储存与展示的容器)
const [numFather, setNumFather] = useState();
//传递给子组件方法获取子组件的变量
const getChildrenVariable = (childrenVariable: any) => {
setNumFather(childrenVariable);
};
return (
<>
<button
onClick={() => {
setVisibleDEtails(true);
}}
>
详情
</button>
<button
onClick={() => {
setVisibleEdit(true);
}}
>
编辑
</button>
<Details
visible={visibleDetails}
unVisible={unVisible}
editCanSee={editCanSee}
/>
<Edit visible={visibleEdit} unVisible={unVisible} />
<Children getChildrenVariable={getChildrenVariable} />
<h2>子组件传过来的变量---{numFather}</h2>
</>
);
}
export default App;
edit子组件
import React from "react";
import { Drawer } from "antd";
import styled from "styled-components";
const Edit = (props: any) => {
const { visible, unVisible } = props;
const onClose = () => {
unVisible();
};
return (
<AddDrawerContainer open={visible} onClose={onClose}>
<div>Edit</div>
</AddDrawerContainer>
);
};
export default Edit;
const AddDrawerContainer = styled(Drawer)``;
详情detail子组件
import React, { useState } from "react";
import { Drawer } from "antd";
import styled from "styled-components";
const Details = (props: any) => {
//将父组件传递过来的变量与方法解构出来使用
const { visible, unVisible, editCanSee } = props;
const onClose = () => {
//调用父组件的方法 --- 通过方法改变变量visible使弹窗关闭(子组件使用父组件的变量与方法只能使用,不能改变),所以通过调用方法在父组件中改变变量
unVisible();
};
//定义向父组件传递的方法
const sendToFather = () => {
editCanSee();
};
/******************巴拉巴拉巴拉巴拉
* 子组件使用父组件的变量和方法 --- 在父组件中写入子组件<></> 将父组件的属性与方法在子组件内以变量和方法的形式传递给子组件
* 子组件通过props接收父组件的属性和方法
* 需要注意的是子组件只能使用父组件的属性和方法,但是不能修改
* 因此父组件中控制子组件弹窗隐藏与显示的变量传递给子组件后需要调用父组件的方法来隐藏
* 同理,在详情中点击编辑按钮,调用父组件的某个方法来控制编辑弹窗的显示与隐藏实现兄弟组件(通过父组件的方法)
*
*******************/
return (
<AddDrawerContainer open={visible} onClose={onClose}>
<div>deatlils</div>
{/* 可以通过子组件再定义一个方法进行调用父组件方法 */}
<button onClick={sendToFather}>编辑</button>
{/* 也可以直接调用父组件方法 */}
<button onClick={editCanSee}>编辑2</button>
</AddDrawerContainer>
);
};
export default Details;
const AddDrawerContainer = styled(Drawer)``;
Children子组件
import React, { useState } from "react";
function Children(props: any) {
//获取父组件的方法
const { getChildrenVariable } = props;
//定义变量进行传递
const [numChildren, setNumChildren] = useState(199);
//调用方法通过形参传递变量
getChildrenVariable(numChildren);
return <h1>Children</h1>;
}
export default Children;
目录结构
over!!!