如何使用react实现插槽?(react组件复合)

13,048 阅读2分钟

组件复合(组件化开发的实现技术之一)

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;