实战——插槽处理 概念 见下图

目的:复用性
我们已经知道了如何把子组件放入父组件,但如果有多个子组件 要传入父组件又该如何完成呢?
因为子组件传入父组件是对象,于是我们可以把它转换为数组形式,以此达到目的
 
多个子组件放入父组件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 import  PropTypes  from  "prop-types" ;const  DemoOne  = function  DemoOne (props ) {  let  { title, x, children } = props;      if  (!children) {     children = [];   } else  if  (!Array .isArray (children)) {     children = [children];   }   return  (     <div  className ="demo-box" >        {children[0]}       <br  />        <h2  className ="title" > {title}</h2 >        <span > {x}</span >        <br  />        {children[1]}     </div >    ); }; DemoOne .defaultProps  = {  x : 0 , }; DemoOne .propTypes  = {  title : PropTypes .string .isRequired ,   x : PropTypes .number , }; export  default  DemoOne ;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 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 ="REACT好好玩哦"  x ={10} >              <span > 哈哈哈哈</span >              <span > 你好</span >          </DemoOne >           <DemoOne  title ="哇卡卡卡" >              <span > 嘿嘿嘿</span >          </DemoOne >          <DemoOne  title ="哈哈哈哈哈"  />      </>  ); 
React.Children 对象但其实我们并不需要自己写对子组件的校验,React有自己的方法。
可以基于 React.Children 对象中提供的方法,对props.children做处理:count\forEach\map\toArray…
开始时,我们会import React,React其实就是一个封装好的对象。
 
1 2 3 4 5 6 7 8 children = React .Children .toArray (children);   if  (!children) {     children = [];   } else  if  (!Array .isArray (children)) {     children = [children];   } 
具名插槽 
当我们要求将子组件放到我们需要的位置时,就可以使用具名组件
 
于是修改后的父组件代码是
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 import  PropTypes  from  "prop-types" ;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 ) =>  {          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 >    ); }; DemoOne .defaultProps  = {  x : 0 , }; DemoOne .propTypes  = {  title : PropTypes .string .isRequired ,   x : PropTypes .number , }; export  default  DemoOne ;
对应的index.jsx,实验一下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 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 ="REACT好好玩哦"  x ={10} >              <span  slot ="footer" > 我是页脚</span >              <span > 哈哈哈哈</span >              <span  slot ="header" > 我是页眉</span >          </DemoOne >           <DemoOne  title ="哇卡卡卡" >              <span > 嘿嘿嘿</span >          </DemoOne >          <DemoOne  title ="哈哈哈哈哈"  />      </>  ); 
待规整部分 实现具名插槽
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 root.render (   <>      <FunctionComponent >        <div  className ='slot-box'  slot ="head" >          我是插槽信息1       </div >        <div  className ='slot-box'  slot ="foot" >          我是插槽信息2       </div >      </FunctionComponent >    </>  ); import  React  from  "react" ;const  FunctionComponent  = function  FunctionComponent (props ) {    let  children = React .Children .toArray (props.children ),         headSlots = children.filter (item  =>props .slot  === 'head' ),         footSlots = children.filter (item  =>props .slot  === 'foot' );     return  <div >          {headSlots}         我是组件内容         {footSlots}     </div >  ;}; export  default  FunctionComponent ;