> 文章列表 > React中实现插槽

React中实现插槽

React中实现插槽

React中实现插槽

设计插槽

在React中实现插槽需要我们自己来实现 主要用到props.children

我们以跟组件作为父组件
创建子组件DemoOne组件


import React from "react";
import ReactDOM from "react-dom/client";
import DemoOne from "./views/DemoOne";const root = ReactDOM.createRoot(document.getElementById("root"));root.render(<><DemoOne title="我是标题" x={10}><span>哈哈哈</span><span>呵呵呵</span></DemoOne><DemoOne title="嘿嘿嘿"><span>嘿嘿嘿</span></DemoOne><DemoOne title="哈哈哈" /></>
);
import React from "react";const DemoOne = function DemoOne(props) {let {title, x, children } = props;console.log(children);return (<div className="demo-BOX">{children}</div>);
};DemoOne.propTypes = {title: PropTypes.string.isRequired,x: PropTypes.number,y: PropTypes.oneOfType([PropTypes.number, PropTypes.bool]),
};export default DemoOne;

这里我们引入了三次子组件
我们先看看子组件中返回的children是什么
React中实现插槽

如果我们要控制每个位置渲染不一样的插槽内容
方式一 是使用数组的形式 但是无法保证每次传入的都是多个插槽值
这时需要使用React.Children 对象中提供的额外方法 对props.children做处理: 其上有count\\forEach\\map\\toArray等方法
在这些方法内部 已经对children做了各种形式的处理
我们可以直接使用

import React from "react";const DemoOne = function DemoOne(props) {let { title, x, children } = props;if (!children) {children = [];} else if (!Array.isArray(children)) {children = [children];}console.log(children);return (<div className="demo-BOX">{children[0]}{children[1]}</div>);
};export default DemoOne;

React中实现插槽

具名插槽

当我们在父组件中对要插入的内容设置上名字后 想要依据不同的名字 渲染在不同的位置 并且顺序也不同时 我们可以采用具名插槽的方式

这里我们设置了footer与header


import React from "react";
import ReactDOM from "react-dom/client";
import DemoOne from "./views/DemoOne";const root = ReactDOM.createRoot(document.getElementById("root"));root.render(<><DemoOne title="我是标题" x={10}><span slot='footer' >哈哈哈</span><span slot='header' >呵呵呵</span></DemoOne><DemoOne title="嘿嘿嘿"><span>嘿嘿嘿</span></DemoOne><DemoOne title="哈哈哈" /></>
);

我们可以先使用React.Children.toArray() 将children都变为数组形式
因为传递进来的插槽信息 都是编译为virtualDOM后传递进来的 而不是传递的标签
所以我们可以直接通过.语法来获取到props对象的slot属性
这里定义三个数组用来存放 header footer 与 default

import React from "react";const DemoOne = function DemoOne(props) {let { title, x, children } = props;children = React.Children.toArray(children);let headerSlot = [],footerSlot = [],defaultSlot = [];children.forEach((child) => {//传递进来的插槽信息 都是编译为virtualDOM后传递进来的 而不是传递的标签let { slot } = child.props;if (slot === "header") {headerSlot.push(child);} else if (slot === "footer") {footerSlot.push(child);} else {defaultSlot.push(child);}});return (<div className="demo-BOX">{headerSlot}<br /><h2 className="title">{title}</h2><span>{x}</span><br />{footerSlot}</div>);
};export default DemoOne;

React中实现插槽