组件复合(组件化开发的实现技术之一)
1.React 组合(插槽实现)
React拥有强大的组合模式,有些组件我们无法提前知晓他们子组件的具体内容如侧边栏sideBar和Dialog对话框,此时react官方建议我们使用一个特殊的props (children)来将这些无法提前预知内容的子组件传递到渲染到结果中;
jsx中的所有内容都会通过children prop传递到父组件中,使用react组合的方式可以实现类似于Vue插槽的功能;
在react中没有插槽的概念,但是我们可以通过组合的形式实现‘插槽’;
- 首先创建一个TopBar.js文件
import React from 'react';
const TopBar = (props) => {
return (
<div>顶部导航</div>
)
}
export default TopBar;
- 再创建一个BottomBar.js文件
import React from 'react';
const BottomBar = (props) => {
return (
<div>底部tab栏</div>
)
}
export default BottomBar;
*创建Home组件
// 创建一个Home组件,在Home组件中引入子组件TopBar和BottomBar
import React, { useEffect } from 'react';
import TopBar from './TopBar.js';
import BottomBar from './BottomBar.js';
const Home = (props) => {
const { children, isShowTopBar, isShowBottomBar, title } = props;
useEffect(() => {
document.title = title;
} , [title]);
return (
<div>
{isShowTopBar && <TopBar />}
// 中间的内容(插槽)
{props.children}
{isShowBottomBar && <BottomBar />}
<BottomBar />
</div>
)
}
export default Home;
- 创建一个Layout组件作为父组件,给Home组件添加‘插槽’
// 创建一个Layout组件
import React from 'react';
import Home from '../Home/Home';
const Layout = (props) => {
return (
<Home isShowTopBar={false} isShowBottomBar={true} title="react实现插槽">
// 首页内容主体(插槽)
<div>
<h1>使用组合的方式实现插槽</h1>
<p>滴答滴答滴答~~~~~~~~~</p>
</div>
</Home>
)
}
export default Layout;
如何实现具名插槽呢?
要实现具名插槽可以从父组件中传递一个对像给子组件,这个对象中的内容可以是jsx,也可以是一段文本内容,还可以是一个事件方法
- 父组件Layout中传值
import React from 'react';
import Home from '../Home/Home';
const Layout = (props) => {
return (
<Home isShowTopBar={false} isShowBottomBar={true} title="react实现插槽">
// 具名插槽
{{
content: (
<div>
<h1>使用组合的方式实现插槽</h1>
<p>滴答滴答滴答~~~~~~~~~</p>
</div>
),
txt: '这是一段文本内容',
clickMe: () => {console.log('这是一个事件方法!')}
}}
</Home>
)
}
export default Layout;
- 子组件Home中使用具名插槽
import React, { useEffect } from 'react';
import TopBar from './TopBar.js';
import BottomBar from './BottomBar.js';
const Home = (props) => {
const { children, isShowTopBar, isShowBottomBar, title } = props;
useEffect(() => {
document.title = title;
} , [title]);
return (
<div>
{isShowTopBar && <TopBar />}
// 使用具名插槽
{children[1].content}
{children[1].txt}
<button onClick={children[1].clickMe}></button>
{isShowBottomBar && <BottomBar />}
<BottomBar />
</div>
)
}
export default Home;